vol: Add VGetVolumeTimed
[openafs.git] / src / vol / volume.h
index 76c3f33..9f43b54 100644 (file)
@@ -95,6 +95,37 @@ extern pthread_t vol_glock_holder;
 #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)
@@ -172,9 +203,12 @@ typedef enum {
     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;
 
 /**
@@ -604,7 +638,11 @@ typedef struct VolumeOnlineSalvage {
     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;
 
 /**
@@ -647,10 +685,15 @@ typedef struct Volume {
     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,
@@ -755,7 +798,8 @@ struct volHeader {
 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 *);
@@ -978,6 +1022,8 @@ extern int VWalkVolumeHeaders(struct DiskPartition64 *dp, const char *partpath,
 
 /* 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)