2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
9 * Portions Copyright (c) 2006-2008 Sine Nomine Associates
15 Institution: The Information Technology Center, Carnegie-Mellon University
22 #include <afs/afssyscalls.h>
25 #define VolumeWriteable(vp) (V_type(vp)==readwriteVolume)
26 #define VolumeWriteable2(vol) (vol.type == readwriteVolume)
27 typedef bit32 FileOffset; /* Offset in this file */
28 #define Date afs_uint32
29 #include "daemon_com.h"
33 /** turn this on if you suspect a volume package locking bug */
34 #define VOL_LOCK_DEBUG 1
38 #define VOL_LOCK_ASSERT_HELD \
39 assert(vol_glock_holder == pthread_self())
40 #define VOL_LOCK_ASSERT_UNHELD \
41 assert(vol_glock_holder == 0)
42 #define _VOL_LOCK_SET_HELD \
43 vol_glock_holder = pthread_self()
44 #define _VOL_LOCK_SET_UNHELD \
46 #define VOL_LOCK_DBG_CV_WAIT_END \
48 VOL_LOCK_ASSERT_UNHELD; \
51 #define VOL_LOCK_DBG_CV_WAIT_BEGIN \
53 VOL_LOCK_ASSERT_HELD; \
54 _VOL_LOCK_SET_UNHELD; \
57 #define VOL_LOCK_ASSERT_HELD
58 #define VOL_LOCK_ASSERT_UNHELD
59 #define VOL_LOCK_DBG_CV_WAIT_BEGIN
60 #define VOL_LOCK_DBG_CV_WAIT_END
64 #ifdef AFS_PTHREAD_ENV
67 extern pthread_mutex_t vol_glock_mutex;
68 extern pthread_mutex_t vol_trans_mutex;
69 extern pthread_cond_t vol_put_volume_cond;
70 extern pthread_cond_t vol_sleep_cond;
71 extern int vol_attach_threads;
73 extern pthread_t vol_glock_holder;
76 assert(pthread_mutex_lock(&vol_glock_mutex) == 0); \
77 assert(vol_glock_holder == 0); \
78 vol_glock_holder = pthread_self(); \
82 VOL_LOCK_ASSERT_HELD; \
83 vol_glock_holder = 0; \
84 assert(pthread_mutex_unlock(&vol_glock_mutex) == 0); \
86 #define VOL_CV_WAIT(cv) \
88 VOL_LOCK_DBG_CV_WAIT_BEGIN; \
89 assert(pthread_cond_wait((cv), &vol_glock_mutex) == 0); \
90 VOL_LOCK_DBG_CV_WAIT_END; \
92 #else /* !VOL_LOCK_DEBUG */
94 assert(pthread_mutex_lock(&vol_glock_mutex) == 0)
96 assert(pthread_mutex_unlock(&vol_glock_mutex) == 0)
97 #define VOL_CV_WAIT(cv) assert(pthread_cond_wait((cv), &vol_glock_mutex) == 0)
98 #endif /* !VOL_LOCK_DEBUG */
99 #define VSALVSYNC_LOCK \
100 assert(pthread_mutex_lock(&vol_salvsync_mutex) == 0)
101 #define VSALVSYNC_UNLOCK \
102 assert(pthread_mutex_unlock(&vol_salvsync_mutex) == 0)
103 #define VTRANS_LOCK \
104 assert(pthread_mutex_lock(&vol_trans_mutex) == 0)
105 #define VTRANS_UNLOCK \
106 assert(pthread_mutex_unlock(&vol_trans_mutex) == 0)
107 #else /* AFS_PTHREAD_ENV */
110 #define VSALVSYNC_LOCK
111 #define VSALVSYNC_UNLOCK
113 #define VTRANS_UNLOCK
114 #endif /* AFS_PTHREAD_ENV */
116 typedef enum { fileServer, /* the fileserver process */
117 volumeUtility, /* volserver, or a single volume salvager (non-dafs) */
118 salvager, /* standalone whole-partition salvager */
119 salvageServer, /* dafs online salvager */
120 debugUtility /* fssync-debug or similar utility */
122 extern ProgramType programType; /* The type of program using the package */
124 /* Some initialization parameters for the volume package */
125 /* Add new initialization parameters here */
126 extern int (*V_BreakVolumeCallbacks) ();
127 extern int (*vol_PollProc) ();
128 #define DOPOLL ((vol_PollProc)? (*vol_PollProc)() : 0)
130 #ifdef AFS_DEMAND_ATTACH_FS
132 * variable error return code based upon programType and DAFS presence
134 #define DAFS_VSALVAGE ((programType == fileServer) ? VSALVAGING : VSALVAGE)
136 #define DAFS_VSALVAGE (VSALVAGE)
139 struct versionStamp { /* Version stamp for critical volume files */
140 bit32 magic; /* Magic number */
141 bit32 version; /* Version number of this file, or software
142 * that created this file */
145 #ifdef AFS_DEMAND_ATTACH_FS
147 * demand attach volume state enumeration.
149 * @note values must be contiguous in order for VIsValidState() to work correctly
152 VOL_STATE_UNATTACHED = 0, /**< volume is unattached */
153 VOL_STATE_PREATTACHED = 1, /**< volume has been pre-attached */
154 VOL_STATE_ATTACHING = 2, /**< volume is transitioning to fully attached */
155 VOL_STATE_ATTACHED = 3, /**< volume has been fully attached */
156 VOL_STATE_UPDATING = 4, /**< volume is updating on-disk structures */
157 VOL_STATE_GET_BITMAP = 5, /**< volume is getting bitmap entries */
158 VOL_STATE_HDR_LOADING = 6, /**< volume is loading disk header */
159 VOL_STATE_HDR_ATTACHING = 7, /**< volume is getting a header from the LRU */
160 VOL_STATE_SHUTTING_DOWN = 8, /**< volume is shutting down */
161 VOL_STATE_GOING_OFFLINE = 9, /**< volume is going offline */
162 VOL_STATE_OFFLINING = 10, /**< volume is transitioning to offline */
163 VOL_STATE_DETACHING = 11, /**< volume is transitioning to detached */
164 VOL_STATE_SALVSYNC_REQ = 12, /**< volume is blocked on a salvsync request */
165 VOL_STATE_SALVAGING = 13, /**< volume is being salvaged */
166 VOL_STATE_ERROR = 14, /**< volume is in an error state */
167 VOL_STATE_VNODE_ALLOC = 15, /**< volume is busy allocating a new vnode */
168 VOL_STATE_VNODE_GET = 16, /**< volume is busy getting vnode disk data */
169 VOL_STATE_VNODE_CLOSE = 17, /**< volume is busy closing vnodes */
170 VOL_STATE_VNODE_RELEASE = 18, /**< volume is busy releasing vnodes */
171 VOL_STATE_VLRU_ADD = 19, /**< volume is busy being added to a VLRU queue */
172 /* please add new states directly above this line */
173 VOL_STATE_FREED = 20, /**< debugging aid */
174 VOL_STATE_COUNT = 21, /**< total number of valid states */
178 * V_attachFlags bits.
181 VOL_HDR_ATTACHED = 0x1, /**< volume header is attached to Volume struct */
182 VOL_HDR_LOADED = 0x2, /**< volume header contents are valid */
183 VOL_HDR_IN_LRU = 0x4, /**< volume header is in LRU */
184 VOL_IN_HASH = 0x8, /**< volume is in hash table */
185 VOL_ON_VBYP_LIST = 0x10, /**< volume is on VByP list */
186 VOL_IS_BUSY = 0x20, /**< volume is not to be free()d */
187 VOL_ON_VLRU = 0x40, /**< volume is on the VLRU */
188 VOL_HDR_DONTSALV = 0x80, /**< volume header DONTSALVAGE flag is set */
191 /* VPrintExtendedCacheStats flags */
192 #define VOL_STATS_PER_CHAIN 0x1 /**< compute simple per-chain stats */
193 #define VOL_STATS_PER_CHAIN2 0x2 /**< compute per-chain stats that require scanning
194 * every element of the chain */
196 /* VLRU_SetOptions options */
197 #define VLRU_SET_THRESH 1
198 #define VLRU_SET_INTERVAL 2
199 #define VLRU_SET_MAX 3
200 #define VLRU_SET_ENABLED 4
206 VLRU_QUEUE_NEW = 0, /**< LRU queue for new volumes */
207 VLRU_QUEUE_MID = 1, /**< survivor generation */
208 VLRU_QUEUE_OLD = 2, /**< old generation */
209 VLRU_QUEUE_CANDIDATE = 3, /**< soft detach candidate pool */
210 VLRU_QUEUE_HELD = 4, /* volumes which are not allowed
211 * to be soft detached */
212 VLRU_QUEUE_INVALID = 5, /**< invalid queue id */
215 /* default scanner timing parameters */
216 #define VLRU_DEFAULT_OFFLINE_THRESH (60*60*2) /* 2 hours */
217 #define VLRU_DEFAULT_OFFLINE_INTERVAL (60*2) /* 2 minutes */
218 #define VLRU_DEFAULT_OFFLINE_MAX 8 /* 8 volumes */
220 #endif /* AFS_DEMAND_ATTACH_FS */
223 /* Magic numbers and version stamps for each type of file */
224 #define VOLUMEHEADERMAGIC ((bit32)0x88a1bb3c)
225 #define VOLUMEINFOMAGIC ((bit32)0x78a1b2c5)
226 #define SMALLINDEXMAGIC 0x99776655
227 #define LARGEINDEXMAGIC 0x88664433
228 #define MOUNTMAGIC 0x9a8b7c6d
229 #define ACLMAGIC 0x88877712
230 #define LINKTABLEMAGIC 0x99877712
232 #define VOLUMEHEADERVERSION 1
233 #define VOLUMEINFOVERSION 1
234 #define SMALLINDEXVERSION 1
235 #define LARGEINDEXVERSION 1
236 #define MOUNTVERSION 1
238 #define LINKTABLEVERSION 1
241 * Define whether we are keeping detailed statistics on volume dealings.
243 #define OPENAFS_VOL_STATS 1
245 #if OPENAFS_VOL_STATS
247 * Define various indices and counts used in keeping volume-level statistics.
249 #define VOL_STATS_NUM_RWINFO_FIELDS 4
251 #define VOL_STATS_SAME_NET 0 /*Within same site (total) */
252 #define VOL_STATS_SAME_NET_AUTH 1 /*Within same site (authenticated);
253 * (must be 1 more than above) */
254 #define VOL_STATS_DIFF_NET 2 /*From external site (total) */
255 #define VOL_STATS_DIFF_NET_AUTH 3 /*From external site (authenticated)
256 * (must be 1 more than above) */
258 #define VOL_STATS_NUM_TIME_RANGES 6
260 #define VOL_STATS_TIME_CAP_0 60 /*60 seconds */
261 #define VOL_STATS_TIME_CAP_1 600 /*10 minutes, in seconds */
262 #define VOL_STATS_TIME_CAP_2 3600 /*1 hour, in seconds */
263 #define VOL_STATS_TIME_CAP_3 86400 /*1 day, in seconds */
264 #define VOL_STATS_TIME_CAP_4 604800 /*1 week, in seconds */
266 #define VOL_STATS_NUM_TIME_FIELDS 6
268 #define VOL_STATS_TIME_IDX_0 0 /*0 secs to 60 secs */
269 #define VOL_STATS_TIME_IDX_1 1 /*1 min to 10 mins */
270 #define VOL_STATS_TIME_IDX_2 2 /*10 mins to 60 mins */
271 #define VOL_STATS_TIME_IDX_3 3 /*1 hr to 24 hrs */
272 #define VOL_STATS_TIME_IDX_4 4 /*1 day to 7 days */
273 #define VOL_STATS_TIME_IDX_5 5 /*Greater than 1 week */
274 #endif /* OPENAFS_VOL_STATS */
276 /* Volume header. This is the contents of the named file representing
277 * the volume. Read-only by the file server!
279 typedef struct VolumeHeader {
280 struct versionStamp stamp; /* Must be first field */
281 VolumeId id; /* Volume number */
282 VolumeId parent; /* Read-write volume number (or this volume
283 * number if this is a read-write volume) */
285 Inode smallVnodeIndex;
286 Inode largeVnodeIndex;
288 Inode volumeMountTable;
293 typedef struct VolumeDiskHeader {
294 struct versionStamp stamp; /* Must be first field */
295 VolumeId id; /* Volume number */
296 VolumeId parent; /* Read-write volume number (or this volume
297 * number if this is a read-write volume) */
298 afs_int32 volumeInfo_lo;
299 afs_int32 smallVnodeIndex_lo;
300 afs_int32 largeVnodeIndex_lo;
301 afs_int32 volumeAcl_lo;
302 afs_int32 volumeMountTable_lo;
303 afs_int32 volumeInfo_hi;
304 afs_int32 smallVnodeIndex_hi;
305 afs_int32 largeVnodeIndex_hi;
306 afs_int32 volumeAcl_hi;
307 afs_int32 volumeMountTable_hi;
308 afs_int32 linkTable_lo;
309 afs_int32 linkTable_hi;
310 /* If you add fields, add them before here and reduce the size of array */
312 } VolumeDiskHeader_t;
314 /* A vnode index file header */
315 struct IndexFileHeader {
316 struct versionStamp stamp;
320 /******************************************************************************/
321 /* Volume Data which is stored on disk and can also be maintained in memory. */
322 /******************************************************************************/
323 typedef struct VolumeDiskData {
324 struct versionStamp stamp; /* Must be first field */
325 VolumeId id; /* Volume id--unique over all systems */
326 #define VNAMESIZE 32 /* including 0 byte */
327 char name[VNAMESIZE]; /* Unofficial name for the volume */
328 byte inUse; /* Volume is being used (perhaps it is online),
329 * or the system crashed while it was used */
330 byte inService; /* Volume in service, not necessarily on line
331 * This bit is set by an operator/system
332 * programmer. Manually taking a volume offline
333 * always clears the inService bit. Taking
334 * it out of service also takes it offline */
335 byte blessed; /* Volume is administratively blessed with
336 * the ability to go on line. Set by a system
337 * administrator. Clearing this bit will
338 * take the volume offline */
339 byte needsSalvaged; /* Volume needs salvaged--an unrecoverable
340 * error occured to the volume. Note: a volume
341 * may still require salvage even if this
342 * flag isn't set--e.g. if a system crash
343 * occurred while the volume was on line. */
344 bit32 uniquifier; /* Next vnode uniquifier for this volume */
346 VolId parentId; /* Id of parent, if type==readonly */
347 VolId cloneId; /* Latest read-only clone, if type==readwrite,
348 * 0 if the volume has never been cloned. Note: the
349 * indicated volume does not necessarily exist (it
350 * may have been deleted since cloning). */
351 VolId backupId; /* Latest backup copy of this read write volume */
352 VolId restoredFromId; /* The id in the dump this volume was restored from--used simply
353 * to make sure that an incremental dump is not restored on top
354 * of something inappropriate: Note: this field itself is NEVER
356 byte needsCallback; /* Set by the salvager if anything was changed
357 * about the volume. Note: this is not set by
358 * clone/makebackups when setting the copy-on-write
359 * flag in directories; this flag is not seen by
361 #define DESTROY_ME 0xD3
362 byte destroyMe; /* If this is set to DESTROY_ME, then the salvager should destroy
363 * this volume; it is bogus (left over from an aborted volume move,
364 * for example). Note: if this flag is on, then inService should
365 * be OFF--only the salvager checks this flag */
366 #ifdef ALPHA_DUX40_ENV
367 #define DONT_SALVAGE 0xE6
368 #else /* ALPHA_DUX40_ENV */
369 #define DONT_SALVAGE 0xE5
370 #endif /* ALPHA_DUX40_ENV */
371 byte dontSalvage; /* If this is on, then don't bother salvaging this volume */
377 /* Administrative stuff */
378 int maxquota; /* Quota maximum, 1K blocks */
379 int minquota; /* Quota minimum, 1K blocks */
380 int maxfiles; /* Maximum number of files (i.e. inodes) */
381 bit32 accountNumber; /* Uninterpreted account number */
382 bit32 owner; /* The person administratively responsible
384 int reserved2[8]; /* Other administrative constraints */
386 /* Resource usage & statistics */
387 int filecount; /* Actual number of files */
388 int diskused; /* Actual disk space used, 1K blocks */
389 int dayUse; /* Metric for today's usage of this volume so far */
390 int weekUse[7]; /* Usage of the volume for the last week.
391 * weekUse[0] is for most recent complete 24 hour period
392 * of measurement; week[6] is 7 days ago */
393 Date dayUseDate; /* Date the dayUse statistics refer to; the week use stats
394 * are the preceding 7 days */
395 unsigned int volUpdateCounter; /*incremented at every update of volume*/
396 int reserved3[10]; /* Other stats here */
398 /* Server supplied dates */
399 Date creationDate; /* Creation date for a read/write
400 * volume; cloning date for original copy of
401 * a readonly volume (replicated volumes have
402 * the same creation date) */
403 Date accessDate; /* Last access time by a user, large granularity */
404 Date updateDate; /* Last modification by user */
405 Date expirationDate; /* 0 if it never expires */
406 Date backupDate; /* last time a backup clone was taken */
408 /* Time that this copy of this volume was made. NEVER backed up. This field is only
409 * set when the copy is created */
412 #if OPENAFS_VOL_STATS
413 bit32 stat_initialized; /*Are the stat fields below set up? */
417 #endif /* OPENAFS_VOL_STATS */
421 char offlineMessage[VMSGSIZE]; /* Why the volume is offline */
422 #if OPENAFS_VOL_STATS
423 #define VOL_STATS_BYTES 128
425 * Keep per-volume aggregate statistics on type and distance of access,
426 * along with authorship info.
428 bit32 stat_reads[VOL_STATS_NUM_RWINFO_FIELDS];
429 bit32 stat_writes[VOL_STATS_NUM_RWINFO_FIELDS];
430 bit32 stat_fileSameAuthor[VOL_STATS_NUM_TIME_FIELDS];
431 bit32 stat_fileDiffAuthor[VOL_STATS_NUM_TIME_FIELDS];
432 bit32 stat_dirSameAuthor[VOL_STATS_NUM_TIME_FIELDS];
433 bit32 stat_dirDiffAuthor[VOL_STATS_NUM_TIME_FIELDS];
435 char motd[VMSGSIZE]; /* Volume "message of the day" */
436 #endif /* OPENAFS_VOL_STATS */
441 /**************************************/
442 /* Memory resident volume information */
443 /**************************************/
446 * global volume package stats.
448 typedef struct VolPkgStats {
449 #ifdef AFS_DEMAND_ATTACH_FS
452 * extended volume package statistics
456 afs_uint32 state_levels[VOL_STATE_COUNT]; /**< volume state transition counters */
459 afs_uint64 hash_looks; /**< number of hash chain element traversals */
460 afs_uint64 hash_reorders; /**< number of hash chain reorders */
461 afs_uint64 salvages; /**< online salvages since fileserver start */
462 afs_uint64 vol_ops; /**< volume operations since fileserver start */
463 #endif /* AFS_DEMAND_ATTACH_FS */
465 afs_uint64 hdr_loads; /**< header loads from disk */
466 afs_uint64 hdr_gets; /**< header pulls out of LRU */
467 afs_uint64 attaches; /**< volume attaches since fileserver start */
468 afs_uint64 soft_detaches; /**< soft detach ops since fileserver start */
470 /* configuration parameters */
471 afs_uint32 hdr_cache_size; /**< size of volume header cache */
473 extern VolPkgStats VStats;
476 * volume header cache supporting structures
478 struct volume_hdr_LRU_stats {
484 struct volume_hdr_LRU_t {
486 struct volume_hdr_LRU_stats stats;
488 extern struct volume_hdr_LRU_t volume_hdr_LRU;
491 * volume hash chain supporting structures
493 typedef struct VolumeHashChainHead {
494 struct rx_queue queue;
496 /* someday we could put a per-chain lock here... */
497 #ifdef AFS_DEMAND_ATTACH_FS
501 /* per-chain statistics */
506 pthread_cond_t chain_busy_cv;
507 #endif /* AFS_DEMAND_ATTACH_FS */
508 } VolumeHashChainHead;
510 typedef struct VolumeHashTable {
513 VolumeHashChainHead * Table;
515 extern VolumeHashTable_t VolumeHashTable;
517 struct VolumeHashChainStats {
518 afs_int32 table_size;
520 #ifdef AFS_DEMAND_ATTACH_FS
521 afs_int32 chain_cacheCheck;
522 afs_int32 chain_busy;
523 afs_uint64 chain_looks;
524 afs_uint64 chain_gets;
525 afs_uint64 chain_reorders;
530 #ifdef AFS_DEMAND_ATTACH_FS
532 * DAFS extended per-volume statistics.
534 * @note this data lives across the entire
535 * lifetime of the fileserver process
537 typedef struct VolumeStats {
539 afs_uint64 hash_lookups; /**< hash table lookups */
540 afs_uint64 hash_short_circuits; /**< short circuited hash lookups (due to cacheCheck) */
541 afs_uint64 hdr_loads; /**< header loads from disk */
542 afs_uint64 hdr_gets; /**< header pulls out of LRU */
543 afs_uint16 attaches; /**< attaches of this volume since fileserver start */
544 afs_uint16 soft_detaches; /**< soft detaches of this volume */
545 afs_uint16 salvages; /**< online salvages since fileserver start */
546 afs_uint16 vol_ops; /**< volume operations since fileserver start */
549 afs_uint32 last_attach; /**< unix timestamp of last VAttach */
550 afs_uint32 last_get; /**< unix timestamp of last VGet/VHold */
551 afs_uint32 last_promote; /**< unix timestamp of last VLRU promote/demote */
552 afs_uint32 last_hdr_get; /**< unix timestamp of last GetVolumeHeader() */
553 afs_uint32 last_hdr_load; /**< unix timestamp of last LoadVolumeHeader() */
554 afs_uint32 last_salvage; /**< unix timestamp of last initiation of an online salvage */
555 afs_uint32 last_salvage_req; /**< unix timestamp of last SALVSYNC request */
556 afs_uint32 last_vol_op; /**< unix timestamp of last volume operation */
560 * DAFS online salvager state.
562 typedef struct VolumeOnlineSalvage {
563 afs_uint32 prio; /**< number of VGetVolume's since salvage requested */
564 int reason; /**< reason for requesting online salvage */
565 byte requested; /**< flag specifying that salvage should be scheduled */
566 byte scheduled; /**< flag specifying whether online salvage scheduled */
567 byte reserved[2]; /**< padding */
568 } VolumeOnlineSalvage;
571 * DAFS Volume LRU state.
573 typedef struct VolumeVLRUState {
574 struct rx_queue lru; /**< VLRU queue for this generation */
575 VLRUQueueName idx; /**< VLRU generation index */
577 #endif /* AFS_DEMAND_ATTACH_FS */
579 typedef struct Volume {
580 struct rx_queue q; /* Volume hash chain pointers */
581 VolumeId hashid; /* Volume number -- for hash table lookup */
582 struct volHeader *header; /* Cached disk data */
583 Device device; /* Unix device for the volume */
585 *partition; /* Information about the Unix partition */
587 IHandle_t *handle; /* Unix inode holding this index */
588 byte *bitmap; /* Index bitmap */
589 afs_uint32 bitmapSize; /* length of bitmap, in bytes */
590 afs_uint32 bitmapOffset; /* Which byte address of the first long to
591 * start search from in bitmap */
592 } vnodeIndex[nVNODECLASSES];
593 IHandle_t *linkHandle;
594 Unique nextVnodeUnique; /* Derived originally from volume uniquifier.
595 * This is the actual next version number to
596 * assign; the uniquifier is bumped by 200 and
597 * and written to disk every 200 file creates
598 * If the volume is shutdown gracefully, the
599 * uniquifier should be rewritten with the
600 * value nextVnodeVersion */
601 IHandle_t *diskDataHandle; /* Unix inode holding general volume info */
602 bit16 vnodeHashOffset; /* Computed by HashOffset function in vnode.h.
603 * Assigned to the volume when initialized.
604 * Added to vnode number for hash table index */
605 byte shuttingDown; /* This volume is going to be detached */
606 byte goingOffline; /* This volume is going offline */
607 bit32 cacheCheck; /* Online sequence number to be used to invalidate vnode cache entries
608 * that stayed around while a volume was offline */
609 short nUsers; /* Number of users of this volume header */
610 byte needsPutBack; /* For a volume utility, this flag is set if we need
611 * to give the volume back when we detach it. The server has
612 * certain modes where it doesn't detach the volume, and
613 * if we give it back spuriously, the server aborts. This field
614 * is meaningless on the file server */
615 byte specialStatus; /* An error code to return on VGetVolume: the
616 * volume is unavailable for the reason quoted,
617 * currently VBUSY or VMOVED */
618 afs_uint32 updateTime; /* Time that this volume was put on the updated
619 * volume list--the list of volumes that will be
620 * salvaged should the file server crash */
621 struct rx_queue vnode_list; /**< linked list of cached vnodes for this volume */
622 #ifdef AFS_DEMAND_ATTACH_FS
623 VolState attach_state; /* what stage of attachment has been completed */
624 afs_uint32 attach_flags; /* flags related to attachment state */
625 pthread_cond_t attach_cv; /* state change condition variable */
626 short nWaiters; /* volume package internal ref count */
627 int chainCacheCheck; /* Volume hash chain cache check */
628 struct rx_queue vol_list; /* per-partition volume list (VByPList) */
630 VolumeOnlineSalvage salvage; /* online salvager state */
631 VolumeStats stats; /* per-volume statistics */
632 VolumeVLRUState vlru; /* state specific to the VLRU */
633 FSSYNC_VolOp_info * pending_vol_op; /* fssync command info for any pending vol ops */
634 #endif /* AFS_DEMAND_ATTACH_FS */
639 VolumeDiskData diskstuff; /* General volume info read from disk */
640 Volume *back; /* back pointer to current volume structure */
643 /* These macros are used to export fields within the volume header. This was added
644 to facilitate changing the actual representation */
646 #define V_device(vp) ((vp)->device)
647 #define V_partition(vp) ((vp)->partition)
648 #define V_diskDataHandle(vp) ((vp)->diskDataHandle)
649 #define V_vnodeIndex(vp) ((vp)->vnodeIndex)
650 #define V_nextVnodeUnique(vp) ((vp)->nextVnodeUnique)
651 #define V_linkHandle(vp) ((vp)->linkHandle)
652 #ifdef AFS_DEMAND_ATTACH_FS
653 #define V_attachState(vp) ((vp)->attach_state)
654 #define V_attachFlags(vp) ((vp)->attach_flags)
655 #define V_attachCV(vp) ((vp)->attach_cv)
656 #endif /* AFS_DEMAND_ATTACH_FS */
658 /* N.B. V_id must be this, rather than vp->id, or some programs will break, probably */
659 #define V_stamp(vp) ((vp)->header->diskstuff.stamp)
660 #define V_id(vp) ((vp)->header->diskstuff.id)
661 #define V_name(vp) ((vp)->header->diskstuff.name)
662 #define V_inUse(vp) ((vp)->header->diskstuff.inUse)
663 #define V_inService(vp) ((vp)->header->diskstuff.inService)
664 #define V_blessed(vp) ((vp)->header->diskstuff.blessed)
665 #define V_needsSalvaged(vp) ((vp)->header->diskstuff.needsSalvaged)
666 #define V_uniquifier(vp) ((vp)->header->diskstuff.uniquifier)
667 #define V_type(vp) ((vp)->header->diskstuff.type)
668 #define V_parentId(vp) ((vp)->header->diskstuff.parentId)
669 #define V_cloneId(vp) ((vp)->header->diskstuff.cloneId)
670 #define V_backupId(vp) ((vp)->header->diskstuff.backupId)
671 #define V_restoredFromId(vp) ((vp)->header->diskstuff.restoredFromId)
672 #define V_needsCallback(vp) ((vp)->header->diskstuff.needsCallback)
673 #define V_destroyMe(vp) ((vp)->header->diskstuff.destroyMe)
674 #define V_dontSalvage(vp) ((vp)->header->diskstuff.dontSalvage)
675 #define V_maxquota(vp) ((vp)->header->diskstuff.maxquota)
676 #define V_minquota(vp) ((vp)->header->diskstuff.minquota)
677 #define V_maxfiles(vp) ((vp)->header->diskstuff.maxfiles)
678 #define V_accountNumber(vp) ((vp)->header->diskstuff.accountNumber)
679 #define V_owner(vp) ((vp)->header->diskstuff.owner)
680 #define V_filecount(vp) ((vp)->header->diskstuff.filecount)
681 #define V_diskused(vp) ((vp)->header->diskstuff.diskused)
682 #define V_dayUse(vp) ((vp)->header->diskstuff.dayUse)
683 #define V_weekUse(vp) ((vp)->header->diskstuff.weekUse)
684 #define V_dayUseDate(vp) ((vp)->header->diskstuff.dayUseDate)
685 #define V_creationDate(vp) ((vp)->header->diskstuff.creationDate)
686 #define V_accessDate(vp) ((vp)->header->diskstuff.accessDate)
687 #define V_updateDate(vp) ((vp)->header->diskstuff.updateDate)
688 #define V_expirationDate(vp) ((vp)->header->diskstuff.expirationDate)
689 #define V_backupDate(vp) ((vp)->header->diskstuff.backupDate)
690 #define V_copyDate(vp) ((vp)->header->diskstuff.copyDate)
691 #define V_offlineMessage(vp) ((vp)->header->diskstuff.offlineMessage)
692 #define V_disk(vp) ((vp)->header->diskstuff)
693 #define V_motd(vp) ((vp)->header->diskstuff.motd)
694 #if OPENAFS_VOL_STATS
695 #define V_stat_initialized(vp) ((vp)->header->diskstuff.stat_initialized)
696 #define V_stat_area(vp) (((vp)->header->diskstuff.stat_reads))
697 #define V_stat_reads(vp, idx) (((vp)->header->diskstuff.stat_reads)[idx])
698 #define V_stat_writes(vp, idx) (((vp)->header->diskstuff.stat_writes)[idx])
699 #define V_stat_fileSameAuthor(vp, idx) (((vp)->header->diskstuff.stat_fileSameAuthor)[idx])
700 #define V_stat_fileDiffAuthor(vp, idx) (((vp)->header->diskstuff.stat_fileDiffAuthor)[idx])
701 #define V_stat_dirSameAuthor(vp, idx) (((vp)->header->diskstuff.stat_dirSameAuthor)[idx])
702 #define V_stat_dirDiffAuthor(vp, idx) (((vp)->header->diskstuff.stat_dirDiffAuthor)[idx])
703 #endif /* OPENAFS_VOL_STATS */
704 #define V_volUpCounter(vp) ((vp)->header->diskstuff.volUpdateCounter)
706 /* File offset computations. The offset values in the volume header are
707 computed with these macros -- when the file is written only!! */
708 #define VOLUME_MOUNT_TABLE_OFFSET(Volume) (sizeof (VolumeDiskData))
709 #define VOLUME_BITMAP_OFFSET(Volume) \
710 (sizeof (VolumeDiskData) + (Volume)->disk.mountTableSize)
713 extern char *VSalvageMessage; /* Canonical message when a volume is forced
715 extern Volume *VGetVolume(Error * ec, Error * client_ec, VolId volumeId);
716 extern Volume *VGetVolume_r(Error * ec, VolId volumeId);
717 extern void VPutVolume(Volume *);
718 extern void VPutVolume_r(Volume *);
719 extern void VOffline(Volume * vp, char *message);
720 extern void VOffline_r(Volume * vp, char *message);
721 extern int VConnectFS(void);
722 extern int VConnectFS_r(void);
723 extern void VDisconnectFS(void);
724 extern void VDisconnectFS_r(void);
725 extern int VChildProcReconnectFS(void);
726 extern Volume *VAttachVolume(Error * ec, VolumeId volumeId, int mode);
727 extern Volume *VAttachVolume_r(Error * ec, VolumeId volumeId, int mode);
728 extern Volume *VCreateVolume(Error * ec, char *partname, VolId volumeId,
730 extern Volume *VCreateVolume_r(Error * ec, char *partname, VolId volumeId,
732 extern VnodeId VAllocBitmapEntry(Error * ec, Volume * vp,
733 struct vnodeIndex *index);
734 extern VnodeId VAllocBitmapEntry_r(Error * ec, Volume * vp,
735 struct vnodeIndex *index, int flags);
736 extern void VFreeBitMapEntry(Error * ec, register struct vnodeIndex *index,
738 extern void VFreeBitMapEntry_r(Error * ec, register struct vnodeIndex *index,
740 extern int VolumeNumber(char *name);
741 extern char *VolumeExternalName(VolumeId volumeId);
742 extern Volume *VAttachVolumeByName(Error * ec, char *partition, char *name,
744 extern Volume *VAttachVolumeByName_r(Error * ec, char *partition, char *name,
746 extern void VShutdown(void);
747 extern void VUpdateVolume(Error * ec, Volume * vp);
748 extern void VUpdateVolume_r(Error * ec, Volume * vp, int flags);
749 extern void VAddToVolumeUpdateList(Error * ec, Volume * vp);
750 extern void VAddToVolumeUpdateList_r(Error * ec, Volume * vp);
751 extern void VDetachVolume(Error * ec, Volume * vp);
752 extern void VDetachVolume_r(Error * ec, Volume * vp);
753 extern void VForceOffline(Volume * vp);
754 extern void VForceOffline_r(Volume * vp, int flags);
755 extern void VBumpVolumeUsage(register Volume * vp);
756 extern void VBumpVolumeUsage_r(register Volume * vp);
757 extern void VSetDiskUsage(void);
758 extern void VPrintCacheStats(void);
759 extern void VReleaseVnodeFiles_r(Volume * vp);
760 extern void VCloseVnodeFiles_r(Volume * vp);
761 extern struct DiskPartition *VGetPartition(char *name, int abortp);
762 extern struct DiskPartition *VGetPartition_r(char *name, int abortp);
763 extern int VInitVolumePackage(ProgramType pt, afs_uint32 nLargeVnodes,
764 afs_uint32 nSmallVnodes, int connect, afs_uint32 volcache);
765 extern void DiskToVolumeHeader(VolumeHeader_t * h, VolumeDiskHeader_t * dh);
766 extern void VolumeHeaderToDisk(VolumeDiskHeader_t * dh, VolumeHeader_t * h);
767 extern void VTakeOffline_r(register Volume * vp);
768 extern void VTakeOffline(register Volume * vp);
769 extern Volume * VLookupVolume_r(Error * ec, VolId volumeId, Volume * hint);
771 #ifdef AFS_DEMAND_ATTACH_FS
772 extern Volume *VPreAttachVolumeByName(Error * ec, char *partition, char *name);
773 extern Volume *VPreAttachVolumeByName_r(Error * ec, char *partition, char *name);
774 extern Volume *VPreAttachVolumeById_r(Error * ec, char * partition,
776 extern Volume *VPreAttachVolumeByVp_r(Error * ec, struct DiskPartition * partp,
777 Volume * vp, VolId volume_id);
778 extern Volume *VGetVolumeByVp_r(Error * ec, Volume * vp);
779 extern int VShutdownByPartition_r(struct DiskPartition * dp);
780 extern int VShutdownVolume_r(Volume * vp);
781 extern int VConnectSALV(void);
782 extern int VConnectSALV_r(void);
783 extern int VReconnectSALV(void);
784 extern int VReconnectSALV_r(void);
785 extern int VDisconnectSALV(void);
786 extern int VDisconnectSALV_r(void);
787 extern void VPrintExtendedCacheStats(int flags);
788 extern void VPrintExtendedCacheStats_r(int flags);
789 extern void VLRU_SetOptions(int option, afs_uint32 val);
790 extern int VSetVolHashSize(int logsize);
791 extern int VRequestSalvage_r(Error * ec, Volume * vp, int reason, int flags);
792 extern int VRegisterVolOp_r(Volume * vp, FSSYNC_VolOp_info * vopinfo);
793 extern int VDeregisterVolOp_r(Volume * vp);
794 extern void VCancelReservation_r(Volume * vp);
795 #endif /* AFS_DEMAND_ATTACH_FS */
796 extern int VVolOpLeaveOnline_r(Volume * vp, FSSYNC_VolOp_info * vopinfo);
797 extern int VVolOpSetVBusy_r(Volume * vp, FSSYNC_VolOp_info * vopinfo);
800 /* Naive formula relating number of file size to number of 1K blocks in file */
801 /* Note: we charge 1 block for 0 length files so the user can't store
802 an inifite number of them; for most files, we give him the inode, vnode,
803 and indirect block overhead, for FREE! */
804 #define nBlocks(bytes) ((afs_sfsize_t)((bytes) == 0? 1: (((afs_sfsize_t)(bytes))+1023)/1024))
806 /* Client process id -- file server sends a Check volumes signal back to the client at this pid */
807 #define CLIENTPID "/vice/vol/clientpid"
809 /* Modes of attachment, for VAttachVolume[ByName] to convey to the file server */
810 #define V_READONLY 1 /* Absolutely no updates will be done to the volume */
811 #define V_CLONE 2 /* Cloning the volume: if it is read/write, then directory
812 * version numbers will change. Header will be updated. If
813 * the volume is read-only, the file server may continue to
814 * server it; it may also continue to server it in read/write
815 * mode if the writes are deferred */
816 #define V_VOLUPD 3 /* General update or volume purge is possible. Volume must
818 #define V_DUMP 4 /* A dump of the volume is requested; the volume can be served
819 * read-only during this time */
820 #define V_SECRETLY 5 /* Secret attach of the volume. This is used to attach a volume
821 * which the file server doesn't know about--and which it shouldn't
822 * know about yet, since the volume has just been created and
823 * is somewhat bogus. Required to make sure that a file server
824 * never knows about more than one copy of the same volume--when
825 * a volume is moved from one partition to another on a single
827 #define V_PEEK 6 /* "Peek" at the volume without telling the fileserver. This is
828 * similar to V_SECRETLY, but read-only. It is used in cases where
829 * not impacting fileserver performance is more important than
830 * getting the most recent data. */
834 /* VUpdateVolume_r flags */
835 #define VOL_UPDATE_WAIT 0x1 /* for demand attach, wait for other exclusive ops to end */
836 #define VOL_UPDATE_NOFORCEOFF 0x2 /* don't force offline on failure. this is to prevent
837 * infinite recursion between vupdate and vforceoff */
839 /* VForceOffline_r flags */
840 #define VOL_FORCEOFF_NOUPDATE 0x1 /* don't force update on forceoff. this is to prevent
841 * infinite recursion between vupdate and vforceoff */
843 /* VSyncVolume_r flags */
844 #define VOL_SYNC_WAIT 0x1 /* for demand attach, wait for other exclusive ops to end */
846 /* VAllocBitmapEntry_r flags */
847 #define VOL_ALLOC_BITMAP_WAIT 0x1 /* for demand attach, wait for other exclusive ops to end */
849 /* VRequestSalvage_r flags */
850 #define VOL_SALVAGE_INVALIDATE_HEADER 0x1 /* for demand attach fs, invalidate volume header cache */
853 #if defined(NEARINODE_HINT)
854 #define V_pref(vp,nearInode) nearInodeHash(V_id(vp),(nearInode)); (nearInode) %= V_partition(vp)->f_files
856 #define V_pref(vp,nearInode) nearInode = 0
857 #endif /* NEARINODE_HINT */
859 #endif /* __volume_h */