#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)
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;
/**
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 */
#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.
*/
#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!
* 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,
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;
} 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 */
* 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 */
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 {
#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])
#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
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);
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);
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);
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);
/* 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 */