vol: remove OPENAFS_VOL_STATS
[openafs.git] / src / vol / volume.h
index bd7b1e7..f9b6473 100644 (file)
@@ -95,6 +95,7 @@ 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 */
+
 #define VSALVSYNC_LOCK MUTEX_ENTER(&vol_salvsync_mutex)
 #define VSALVSYNC_UNLOCK MUTEX_EXIT(&vol_salvsync_mutex)
 #define VTRANS_LOCK MUTEX_ENTER(&vol_trans_mutex)
@@ -175,9 +176,11 @@ typedef enum {
     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 */
+    VOL_STATE_SCANNING_RXCALLS  = 22,   /**< volume is scanning vp->rx_call_list
+                                         *   to interrupt RX calls */
     /* please add new states directly above this line */
-    VOL_STATE_FREED             = 22,   /**< debugging aid */
-    VOL_STATE_COUNT             = 23    /**< total number of valid states */
+    VOL_STATE_FREED             = 23,   /**< debugging aid */
+    VOL_STATE_COUNT             = 24    /**< total number of valid states */
 } VolState;
 
 /**
@@ -249,6 +252,28 @@ typedef struct VolumePackageOptions {
     afs_int32 canUseSALVSYNC;     /**< can we use the SALVSYNC channel? (DAFS) */
     afs_int32 unsafe_attach;      /**< can we bypass checking the inUse vol
                                    *   header on attach? */
+    void (*interrupt_rxcall) (struct rx_call *call, afs_int32 error);
+                                  /**< callback to interrupt RX calls accessing
+                                   *   a going-offline volume */
+    afs_int32 offline_timeout;    /**< how long (in seconds) to wait before
+                                   *   interrupting RX calls accessing a
+                                   *   going-offline volume. -1 disables,
+                                   *   0 means immediately. */
+    afs_int32 offline_shutdown_timeout;
+                                  /**< how long (in seconds) to wait before
+                                   *   interrupting RX calls accessing a
+                                   *   going-offline volume during shutdown.
+                                   *   -1 disables, 0 means immediately.
+                                   *   Note that the timeout time is calculated
+                                   *   once, when we encounter the first going-
+                                   *   offline volume during shutdown. So if we
+                                   *   encounter multiple going-offline volumes
+                                   *   during shutdown, we will still only wait
+                                   *   for this amount of time in total, not e.g.
+                                   *   for each going-offline volume encountered. */
+    afs_int32 usage_threshold;    /*< number of accesses before writing volume header */
+    afs_int32 usage_rate_limit;   /*< minimum number of seconds before writing volume
+                                   *  header, after usage_threshold is exceeded */
 } VolumePackageOptions;
 
 /* Magic numbers and version stamps for each type of file */
@@ -268,12 +293,7 @@ typedef struct VolumePackageOptions {
 #define ACLVERSION             1
 #define LINKTABLEVERSION       1
 
-/*
- * Define whether we are keeping detailed statistics on volume dealings.
- */
-#define OPENAFS_VOL_STATS      1
 
-#if OPENAFS_VOL_STATS
 /*
  * Define various indices and counts used in keeping volume-level statistics.
  */
@@ -302,7 +322,6 @@ typedef struct VolumePackageOptions {
 #define VOL_STATS_TIME_IDX_3   3       /*1 hr to 24 hrs */
 #define VOL_STATS_TIME_IDX_4   4       /*1 day to 7 days */
 #define VOL_STATS_TIME_IDX_5   5       /*Greater than 1 week */
-#endif /* OPENAFS_VOL_STATS */
 
 /* Volume header.  This is the contents of the named file representing
  * the volume.  Read-only by the file server!
@@ -440,17 +459,12 @@ typedef struct VolumeDiskData {
      * set when the copy is created */
     Date copyDate;
 
-#if OPENAFS_VOL_STATS
     bit32 stat_initialized;    /*Are the stat fields below set up? */
     bit32 reserved4[7];
-#else
-    bit32 reserved4[8];
-#endif                         /* OPENAFS_VOL_STATS */
 
     /* messages */
 #define VMSGSIZE 128
     char offlineMessage[VMSGSIZE];     /* Why the volume is offline */
-#if OPENAFS_VOL_STATS
 #define VOL_STATS_BYTES 128
     /*
      * Keep per-volume aggregate statistics on type and distance of access,
@@ -462,9 +476,6 @@ typedef struct VolumeDiskData {
     bit32 stat_fileDiffAuthor[VOL_STATS_NUM_TIME_FIELDS];
     bit32 stat_dirSameAuthor[VOL_STATS_NUM_TIME_FIELDS];
     bit32 stat_dirDiffAuthor[VOL_STATS_NUM_TIME_FIELDS];
-#else
-    char motd[VMSGSIZE];       /* Volume "message of the day" */
-#endif                         /* OPENAFS_VOL_STATS */
 
 } VolumeDiskData;
 
@@ -623,6 +634,14 @@ typedef struct VolumeVLRUState {
 } VolumeVLRUState;
 #endif /* AFS_DEMAND_ATTACH_FS */
 
+/**
+ * node for a volume's rx_call_list.
+ */
+struct VCallByVol {
+    struct rx_queue q;
+    struct rx_call *call;
+};
+
 typedef struct Volume {
     struct rx_queue q;          /* Volume hash chain pointers */
     VolumeId hashid;           /* Volume number -- for hash table lookup */
@@ -654,10 +673,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,
@@ -667,6 +691,8 @@ typedef struct Volume {
                                 * volume list--the list of volumes that will be
                                 * salvaged should the file server crash */
     struct rx_queue vnode_list; /**< linked list of cached vnodes for this volume */
+    struct rx_queue rx_call_list; /**< linked list of split RX calls using this
+                                   *   volume (fileserver only) */
 #ifdef AFS_DEMAND_ATTACH_FS
     VolState attach_state;      /* what stage of attachment has been completed */
     afs_uint32 attach_flags;    /* flags related to attachment state */
@@ -680,6 +706,8 @@ typedef struct Volume {
     VolumeVLRUState vlru;         /* state specific to the VLRU */
     FSSYNC_VolOp_info * pending_vol_op;  /* fssync command info for any pending vol ops */
 #endif /* AFS_DEMAND_ATTACH_FS */
+    int usage_bumps_outstanding; /**< to rate limit the usage update i/o by accesses */
+    int usage_bumps_next_write;  /**< to rate limit the usage update i/o by time */
 } Volume;
 
 struct volHeader {
@@ -740,7 +768,6 @@ struct volHeader {
 #define V_offlineMessage(vp)   ((vp)->header->diskstuff.offlineMessage)
 #define V_disk(vp)             ((vp)->header->diskstuff)
 #define V_motd(vp)             ((vp)->header->diskstuff.motd)
-#if OPENAFS_VOL_STATS
 #define V_stat_initialized(vp) ((vp)->header->diskstuff.stat_initialized)
 #define V_stat_area(vp)                (((vp)->header->diskstuff.stat_reads))
 #define V_stat_reads(vp, idx)  (((vp)->header->diskstuff.stat_reads)[idx])
@@ -749,7 +776,6 @@ struct volHeader {
 #define V_stat_fileDiffAuthor(vp, idx) (((vp)->header->diskstuff.stat_fileDiffAuthor)[idx])
 #define V_stat_dirSameAuthor(vp, idx)  (((vp)->header->diskstuff.stat_dirSameAuthor)[idx])
 #define V_stat_dirDiffAuthor(vp, idx)  (((vp)->header->diskstuff.stat_dirDiffAuthor)[idx])
-#endif /* OPENAFS_VOL_STATS */
 #define V_volUpCounter(vp)             ((vp)->header->diskstuff.volUpdateCounter)
 
 /* File offset computations.  The offset values in the volume header are
@@ -762,9 +788,11 @@ 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 *VGetVolumeWithCall(Error * ec, Error * client_ec, VolId volumeId,
+                                  const struct timespec *ts, struct VCallByVol *cbv);
 extern Volume *VGetVolume_r(Error * ec, VolId volumeId);
 extern void VPutVolume(Volume *);
+extern void VPutVolumeWithCall(Volume *vp, struct VCallByVol *cbv);
 extern void VPutVolume_r(Volume *);
 extern void VOffline(Volume * vp, char *message);
 extern void VOffline_r(Volume * vp, char *message);
@@ -783,10 +811,10 @@ extern int VAllocBitmapEntry(Error * ec, Volume * vp,
                             struct vnodeIndex *index);
 extern int VAllocBitmapEntry_r(Error * ec, Volume * vp,
                               struct vnodeIndex *index, int flags);
-extern void VFreeBitMapEntry(Error * ec, struct vnodeIndex *index,
+extern void VFreeBitMapEntry(Error * ec, Volume *vp, struct vnodeIndex *index,
                             unsigned bitNumber);
-extern void VFreeBitMapEntry_r(Error * ec, struct vnodeIndex *index,
-                              unsigned bitNumber);
+extern void VFreeBitMapEntry_r(Error * ec, Volume *vp, struct vnodeIndex *index,
+                              unsigned bitNumber, int flags);
 extern int VolumeNumber(char *name);
 extern char *VolumeExternalName(VolumeId volumeId);
 extern int VolumeExternalName_r(VolumeId volumeId, char *name, size_t len);
@@ -824,6 +852,7 @@ extern Volume * VLookupVolume_r(Error * ec, VolId volumeId, Volume * hint);
 extern void VGetVolumePath(Error * ec, VolId volumeId, char **partitionp,
                           char **namep);
 extern char *vol_DevName(dev_t adev, char *wpath);
+extern afs_int32 VIsGoingOffline(struct Volume *vp);
 
 struct VLockFile;
 extern void VLockFileInit(struct VLockFile *lf, const char *path);
@@ -859,13 +888,15 @@ extern int VDeregisterVolOp_r(Volume * vp);
 extern void VCancelReservation_r(Volume * vp);
 extern int VChildProcReconnectFS_r(void);
 extern void VOfflineForVolOp_r(Error *ec, Volume *vp, char *message);
+#endif /* AFS_DEMAND_ATTACH_FS */
 
+#if defined(AFS_DEMAND_ATTACH_FS) || defined(AFS_DEMAND_ATTACH_UTIL)
 struct VDiskLock;
 extern void VDiskLockInit(struct VDiskLock *dl, struct VLockFile *lf,
                           afs_uint32 offset);
 extern int VGetDiskLock(struct VDiskLock *dl, int locktype, int nonblock);
 extern void VReleaseDiskLock(struct VDiskLock *dl, int locktype);
-#endif /* AFS_DEMAND_ATTACH_FS */
+#endif /* AFS_DEMAND_ATTACH_FS || AFS_DEMAND_ATTACH_UTIL */
 extern int VVolOpLeaveOnline_r(Volume * vp, FSSYNC_VolOp_info * vopinfo);
 extern int VVolOpLeaveOnlineNoHeader_r(Volume * vp, FSSYNC_VolOp_info * vopinfo);
 extern int VVolOpSetVBusy_r(Volume * vp, FSSYNC_VolOp_info * vopinfo);
@@ -983,9 +1014,11 @@ extern int VWalkVolumeHeaders(struct DiskPartition64 *dp, const char *partpath,
 /* VAllocBitmapEntry_r flags */
 #define VOL_ALLOC_BITMAP_WAIT    0x1  /* for demand attach, wait for other exclusive ops to end */
 
+/* VFreeBitMapEntry_r flags */
+#define VOL_FREE_BITMAP_WAIT     0x1  /* for demand attach, wait for other exclusive ops to end */
+
 /* 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
+#define VOL_SALVAGE_NO_OFFLINE        0x1 /* we do not need to wait to offline the volume; it has
                                            * not been fully attached */