#define VOL_UNLOCK MUTEX_EXIT(&vol_glock_mutex)
#define VOL_CV_WAIT(cv) CV_WAIT((cv), &vol_glock_mutex)
#endif /* !VOL_LOCK_DEBUG */
+
+/**
+ * @param[in] cv cond var
+ * @param[in] ts deadline, or NULL to wait forever
+ * @param[out] timedout set to 1 if we returned due to the deadline, 0 if we
+ * returned due to the cond var getting signalled. If
+ * NULL, it is ignored.
+ */
+static_inline void
+VOL_CV_TIMEDWAIT(pthread_cond_t *cv, const struct timespec *ts, int *timedout)
+{
+ int code;
+ if (timedout) {
+ *timedout = 0;
+ }
+ if (!ts) {
+ VOL_CV_WAIT(cv);
+ return;
+ }
+ VOL_LOCK_DBG_CV_WAIT_BEGIN;
+ code = CV_TIMEDWAIT(cv, &vol_glock_mutex, ts);
+ VOL_LOCK_DBG_CV_WAIT_END;
+ if (code == ETIMEDOUT) {
+ code = 0;
+ if (timedout) {
+ *timedout = 1;
+ }
+ }
+ osi_Assert(code == 0);
+}
+
#define VSALVSYNC_LOCK MUTEX_ENTER(&vol_salvsync_mutex)
#define VSALVSYNC_UNLOCK MUTEX_EXIT(&vol_salvsync_mutex)
#define VTRANS_LOCK MUTEX_ENTER(&vol_trans_mutex)
VOL_STATE_VNODE_RELEASE = 18, /**< volume is busy releasing vnodes */
VOL_STATE_VLRU_ADD = 19, /**< volume is busy being added to a VLRU queue */
VOL_STATE_DELETED = 20, /**< volume has been deleted by the volserver */
+ VOL_STATE_SALVAGE_REQ = 21, /**< volume has been requested to be salvaged,
+ * but is waiting for other users to go away
+ * so it can be offlined */
/* please add new states directly above this line */
- VOL_STATE_FREED = 21, /**< debugging aid */
- VOL_STATE_COUNT = 22 /**< total number of valid states */
+ VOL_STATE_FREED = 22, /**< debugging aid */
+ VOL_STATE_COUNT = 23 /**< total number of valid states */
} VolState;
/**
int reason; /**< reason for requesting online salvage */
byte requested; /**< flag specifying that salvage should be scheduled */
byte scheduled; /**< flag specifying whether online salvage scheduled */
- byte reserved[2]; /**< padding */
+ byte scheduling; /**< if nonzero, this volume has entered
+ * VCheckSalvage(), so if we recurse into
+ * VCheckSalvage() with this set, exit immediately
+ * to avoid recursing forever */
+ byte reserved[1]; /**< padding */
} VolumeOnlineSalvage;
/**
bit32 cacheCheck; /* Online sequence number to be used to invalidate vnode cache entries
* that stayed around while a volume was offline */
short nUsers; /* Number of users of this volume header */
- byte needsPutBack; /* For a volume utility, this flag is set if we need
- * to give the volume back when we detach it. The server has
+#define VOL_PUTBACK 1
+#define VOL_PUTBACK_DELETE 2
+ byte needsPutBack; /* For a volume utility, this flag is set to VOL_PUTBACK if we
+ * need to give the volume back when we detach it. The server has
* certain modes where it doesn't detach the volume, and
- * if we give it back spuriously, the server aborts. This field
+ * if we give it back spuriously, the server aborts. If set to
+ * VOL_PUTBACK_DELETE, it indicates that we need to tell the
+ * fileserver that the volume is gone entirely, instead of just
+ * giving the volume back to the fileserver. This field
* is meaningless on the file server */
byte specialStatus; /* An error code to return on VGetVolume: the
* volume is unavailable for the reason quoted,
extern char *VSalvageMessage; /* Canonical message when a volume is forced
* offline */
extern Volume *VGetVolume(Error * ec, Error * client_ec, VolId volumeId);
-extern Volume *VGetVolumeNoWait(Error * ec, Error * client_ec, VolId volumeId);
+extern Volume *VGetVolumeTimed(Error * ec, Error * client_ec, VolId volumeId,
+ const struct timespec *ts);
extern Volume *VGetVolume_r(Error * ec, VolId volumeId);
extern void VPutVolume(Volume *);
extern void VPutVolume_r(Volume *);
/* VRequestSalvage_r flags */
#define VOL_SALVAGE_INVALIDATE_HEADER 0x1 /* for demand attach fs, invalidate volume header cache */
+#define VOL_SALVAGE_NO_OFFLINE 0x2 /* we do not need to wait to offline the volume; it has
+ * not been fully attached */
#if defined(NEARINODE_HINT)