Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / vol / volume.h
CommitLineData
805e021f
CE
1/*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
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
8 *
9 * Portions Copyright (c) 2006-2008 Sine Nomine Associates
10 */
11
12/*
13 System: VICE-TWO
14 Module: volume.h
15 Institution: The Information Technology Center, Carnegie-Mellon University
16
17 */
18
19#ifndef __volume_h
20#define __volume_h 1
21
22#include <afs/afssyscalls.h>
23#include "voldefs.h"
24#include "ihandle.h"
25#define VolumeWriteable(vp) (V_type(vp)==readwriteVolume)
26#define VolumeWriteable2(vol) (vol.type == readwriteVolume)
27typedef bit32 FileOffset; /* Offset in this file */
28#define Date afs_uint32
29#include "daemon_com.h"
30#include "fssync.h"
31
32#if 0
33/** turn this on if you suspect a volume package locking bug */
34#define VOL_LOCK_DEBUG 1
35#endif
36
37#ifdef VOL_LOCK_DEBUG
38#define VOL_LOCK_ASSERT_HELD \
39 opr_Assert(vol_glock_holder == pthread_self())
40#define VOL_LOCK_ASSERT_UNHELD \
41 opr_Assert(vol_glock_holder == 0)
42#define _VOL_LOCK_SET_HELD \
43 vol_glock_holder = pthread_self()
44#define _VOL_LOCK_SET_UNHELD \
45 vol_glock_holder = 0
46#define VOL_LOCK_DBG_CV_WAIT_END \
47 do { \
48 VOL_LOCK_ASSERT_UNHELD; \
49 _VOL_LOCK_SET_HELD; \
50 } while(0)
51#define VOL_LOCK_DBG_CV_WAIT_BEGIN \
52 do { \
53 VOL_LOCK_ASSERT_HELD; \
54 _VOL_LOCK_SET_UNHELD; \
55 } while(0)
56#else
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
61#endif
62
63
64#ifdef AFS_PTHREAD_ENV
65#include <pthread.h>
66extern pthread_mutex_t vol_glock_mutex;
67extern pthread_mutex_t vol_trans_mutex;
68extern pthread_cond_t vol_put_volume_cond;
69extern pthread_cond_t vol_sleep_cond;
70extern pthread_cond_t vol_vinit_cond;
71extern ih_init_params vol_io_params;
72extern int vol_attach_threads;
73#ifdef VOL_LOCK_DEBUG
74extern pthread_t vol_glock_holder;
75#define VOL_LOCK \
76 do { \
77 opr_mutex_enter(&vol_glock_mutex); \
78 VOL_LOCK_ASSERT_UNHELD; \
79 _VOL_LOCK_SET_HELD; \
80 } while (0)
81#define VOL_UNLOCK \
82 do { \
83 VOL_LOCK_ASSERT_HELD; \
84 _VOL_LOCK_SET_UNHELD; \
85 opr_mutex_exit(&vol_glock_mutex); \
86 } while (0)
87#define VOL_CV_WAIT(cv) \
88 do { \
89 VOL_LOCK_DBG_CV_WAIT_BEGIN; \
90 opr_cv_wait((cv), &vol_glock_mutex); \
91 VOL_LOCK_DBG_CV_WAIT_END; \
92 } while (0)
93#else /* !VOL_LOCK_DEBUG */
94#define VOL_LOCK opr_mutex_enter(&vol_glock_mutex)
95#define VOL_UNLOCK opr_mutex_exit(&vol_glock_mutex)
96#define VOL_CV_WAIT(cv) opr_cv_wait((cv), &vol_glock_mutex)
97#endif /* !VOL_LOCK_DEBUG */
98
99#define VSALVSYNC_LOCK opr_mutex_enter(&vol_salvsync_mutex)
100#define VSALVSYNC_UNLOCK opr_mutex_exit(&vol_salvsync_mutex)
101#define VTRANS_LOCK opr_mutex_enter(&vol_trans_mutex)
102#define VTRANS_UNLOCK opr_mutex_exit(&vol_trans_mutex)
103#else /* AFS_PTHREAD_ENV */
104#define VOL_LOCK
105#define VOL_UNLOCK
106#define VSALVSYNC_LOCK
107#define VSALVSYNC_UNLOCK
108#define VTRANS_LOCK
109#define VTRANS_UNLOCK
110#endif /* AFS_PTHREAD_ENV */
111
112/**
113 * volume package program type enumeration.
114 */
115typedef enum {
116 fileServer = 1, /**< the fileserver process */
117 volumeUtility = 2, /**< any miscellaneous volume utility */
118 salvager = 3, /**< standalone whole-partition salvager */
119 salvageServer = 4, /**< dafs online salvager */
120 debugUtility = 5, /**< fssync-debug or similar utility */
121 volumeServer = 6, /**< the volserver process */
122 volumeSalvager = 7 /**< the standalone single-volume salvager */
123} ProgramType;
124extern ProgramType programType; /* The type of program using the package */
125
126/* Some initialization parameters for the volume package */
127/* Add new initialization parameters here */
128extern int (*V_BreakVolumeCallbacks) (VolumeId);
129extern int (*vol_PollProc) (void);
130
131#define DOPOLL ((vol_PollProc)? (*vol_PollProc)() : 0)
132
133#ifdef AFS_DEMAND_ATTACH_FS
134/**
135 * variable error return code based upon programType and DAFS presence
136 */
137#define DAFS_VSALVAGE ((programType == fileServer) ? VSALVAGING : VSALVAGE)
138#else
139#define DAFS_VSALVAGE (VSALVAGE)
140#endif
141
142struct versionStamp { /* Version stamp for critical volume files */
143 bit32 magic; /* Magic number */
144 bit32 version; /* Version number of this file, or software
145 * that created this file */
146};
147
148#ifdef AFS_DEMAND_ATTACH_FS
149/**
150 * demand attach volume state enumeration.
151 *
152 * @note values must be contiguous in order for VIsValidState() to work correctly
153 */
154typedef enum {
155 VOL_STATE_UNATTACHED = 0, /**< volume is unattached */
156 VOL_STATE_PREATTACHED = 1, /**< volume has been pre-attached */
157 VOL_STATE_ATTACHING = 2, /**< volume is transitioning to fully attached */
158 VOL_STATE_ATTACHED = 3, /**< volume has been fully attached */
159 VOL_STATE_UPDATING = 4, /**< volume is updating on-disk structures */
160 VOL_STATE_GET_BITMAP = 5, /**< volume is getting bitmap entries */
161 VOL_STATE_HDR_LOADING = 6, /**< volume is loading disk header */
162 VOL_STATE_HDR_ATTACHING = 7, /**< volume is getting a header from the LRU */
163 VOL_STATE_SHUTTING_DOWN = 8, /**< volume is shutting down */
164 VOL_STATE_GOING_OFFLINE = 9, /**< volume is going offline */
165 VOL_STATE_OFFLINING = 10, /**< volume is transitioning to offline */
166 VOL_STATE_DETACHING = 11, /**< volume is transitioning to detached */
167 VOL_STATE_SALVSYNC_REQ = 12, /**< volume is blocked on a salvsync request */
168 VOL_STATE_SALVAGING = 13, /**< volume is being salvaged */
169 VOL_STATE_ERROR = 14, /**< volume is in an error state */
170 VOL_STATE_VNODE_ALLOC = 15, /**< volume is busy allocating a new vnode */
171 VOL_STATE_VNODE_GET = 16, /**< volume is busy getting vnode disk data */
172 VOL_STATE_VNODE_CLOSE = 17, /**< volume is busy closing vnodes */
173 VOL_STATE_VNODE_RELEASE = 18, /**< volume is busy releasing vnodes */
174 VOL_STATE_VLRU_ADD = 19, /**< volume is busy being added to a VLRU queue */
175 VOL_STATE_DELETED = 20, /**< volume has been deleted by the volserver */
176 VOL_STATE_SALVAGE_REQ = 21, /**< volume has been requested to be salvaged,
177 * but is waiting for other users to go away
178 * so it can be offlined */
179 VOL_STATE_SCANNING_RXCALLS = 22, /**< volume is scanning vp->rx_call_list
180 * to interrupt RX calls */
181 /* please add new states directly above this line */
182 VOL_STATE_FREED = 23, /**< debugging aid */
183 VOL_STATE_COUNT = 24 /**< total number of valid states */
184} VolState;
185
186/**
187 * V_attachFlags bits.
188 */
189enum VolFlags {
190 VOL_HDR_ATTACHED = 0x1, /**< volume header is attached to Volume struct */
191 VOL_HDR_LOADED = 0x2, /**< volume header contents are valid */
192 VOL_HDR_IN_LRU = 0x4, /**< volume header is in LRU */
193 VOL_IN_HASH = 0x8, /**< volume is in hash table */
194 VOL_ON_VBYP_LIST = 0x10, /**< volume is on VByP list */
195 VOL_IS_BUSY = 0x20, /**< volume is not to be free()d */
196 VOL_ON_VLRU = 0x40, /**< volume is on the VLRU */
197 VOL_HDR_DONTSALV = 0x80, /**< volume header DONTSALVAGE flag is set */
198 VOL_LOCKED = 0x100 /**< volume is disk-locked (@see VLockVolumeNB) */
199};
200
201/* VPrintExtendedCacheStats flags */
202#define VOL_STATS_PER_CHAIN 0x1 /**< compute simple per-chain stats */
203#define VOL_STATS_PER_CHAIN2 0x2 /**< compute per-chain stats that require scanning
204 * every element of the chain */
205
206/* VLRU_SetOptions options */
207#define VLRU_SET_THRESH 1
208#define VLRU_SET_INTERVAL 2
209#define VLRU_SET_MAX 3
210#define VLRU_SET_ENABLED 4
211
212/**
213 * VLRU queue names.
214 */
215typedef enum {
216 VLRU_QUEUE_NEW = 0, /**< LRU queue for new volumes */
217 VLRU_QUEUE_MID = 1, /**< survivor generation */
218 VLRU_QUEUE_OLD = 2, /**< old generation */
219 VLRU_QUEUE_CANDIDATE = 3, /**< soft detach candidate pool */
220 VLRU_QUEUE_HELD = 4, /* volumes which are not allowed
221 * to be soft detached */
222 VLRU_QUEUE_INVALID = 5 /**< invalid queue id */
223} VLRUQueueName;
224
225/* default scanner timing parameters */
226#define VLRU_DEFAULT_OFFLINE_THRESH (60*60*2) /* 2 hours */
227#define VLRU_DEFAULT_OFFLINE_INTERVAL (60*2) /* 2 minutes */
228#define VLRU_DEFAULT_OFFLINE_MAX 8 /* 8 volumes */
229
230
231/**
232 * DAFS thread-specific options structure
233 */
234typedef struct VThreadOptions {
235 int disallow_salvsync; /**< whether or not salvsync calls are allowed
236 * on this thread (deadlock prevention). */
237} VThreadOptions_t;
238extern pthread_key_t VThread_key;
239extern VThreadOptions_t VThread_defaults;
240
241#endif /* AFS_DEMAND_ATTACH_FS */
242
243typedef struct VolumePackageOptions {
244 afs_uint32 nLargeVnodes; /**< size of large vnode cache */
245 afs_uint32 nSmallVnodes; /**< size of small vnode cache */
246 afs_uint32 volcache; /**< size of volume header cache */
247
248 afs_int32 canScheduleSalvage; /**< can we schedule salvages? (DAFS) */
249 /* (if 'no', we will just error out if we
250 * find a bad vol) */
251 afs_int32 canUseFSSYNC; /**< can we use the FSSYNC channel? */
252 afs_int32 canUseSALVSYNC; /**< can we use the SALVSYNC channel? (DAFS) */
253 afs_int32 unsafe_attach; /**< can we bypass checking the inUse vol
254 * header on attach? */
255 void (*interrupt_rxcall) (struct rx_call *call, afs_int32 error);
256 /**< callback to interrupt RX calls accessing
257 * a going-offline volume */
258 afs_int32 offline_timeout; /**< how long (in seconds) to wait before
259 * interrupting RX calls accessing a
260 * going-offline volume. -1 disables,
261 * 0 means immediately. */
262 afs_int32 offline_shutdown_timeout;
263 /**< how long (in seconds) to wait before
264 * interrupting RX calls accessing a
265 * going-offline volume during shutdown.
266 * -1 disables, 0 means immediately.
267 * Note that the timeout time is calculated
268 * once, when we encounter the first going-
269 * offline volume during shutdown. So if we
270 * encounter multiple going-offline volumes
271 * during shutdown, we will still only wait
272 * for this amount of time in total, not e.g.
273 * for each going-offline volume encountered. */
274 afs_int32 usage_threshold; /*< number of accesses before writing volume header */
275 afs_int32 usage_rate_limit; /*< minimum number of seconds before writing volume
276 * header, after usage_threshold is exceeded */
277} VolumePackageOptions;
278
279/* Magic numbers and version stamps for each type of file */
280#define VOLUMEHEADERMAGIC ((bit32)0x88a1bb3c)
281#define VOLUMEINFOMAGIC ((bit32)0x78a1b2c5)
282#define SMALLINDEXMAGIC 0x99776655
283#define LARGEINDEXMAGIC 0x88664433
284#define MOUNTMAGIC 0x9a8b7c6d
285#define ACLMAGIC 0x88877712
286#define LINKTABLEMAGIC 0x99877712
287
288#define VOLUMEHEADERVERSION 1
289#define VOLUMEINFOVERSION 1
290#define SMALLINDEXVERSION 1
291#define LARGEINDEXVERSION 1
292#define MOUNTVERSION 1
293#define ACLVERSION 1
294#define LINKTABLEVERSION 1
295
296
297/*
298 * Define various indices and counts used in keeping volume-level statistics.
299 */
300#define VOL_STATS_NUM_RWINFO_FIELDS 4
301
302#define VOL_STATS_SAME_NET 0 /*Within same site (total) */
303#define VOL_STATS_SAME_NET_AUTH 1 /*Within same site (authenticated);
304 * (must be 1 more than above) */
305#define VOL_STATS_DIFF_NET 2 /*From external site (total) */
306#define VOL_STATS_DIFF_NET_AUTH 3 /*From external site (authenticated)
307 * (must be 1 more than above) */
308
309#define VOL_STATS_NUM_TIME_RANGES 6
310
311#define VOL_STATS_TIME_CAP_0 60 /*60 seconds */
312#define VOL_STATS_TIME_CAP_1 600 /*10 minutes, in seconds */
313#define VOL_STATS_TIME_CAP_2 3600 /*1 hour, in seconds */
314#define VOL_STATS_TIME_CAP_3 86400 /*1 day, in seconds */
315#define VOL_STATS_TIME_CAP_4 604800 /*1 week, in seconds */
316
317#define VOL_STATS_NUM_TIME_FIELDS 6
318
319#define VOL_STATS_TIME_IDX_0 0 /*0 secs to 60 secs */
320#define VOL_STATS_TIME_IDX_1 1 /*1 min to 10 mins */
321#define VOL_STATS_TIME_IDX_2 2 /*10 mins to 60 mins */
322#define VOL_STATS_TIME_IDX_3 3 /*1 hr to 24 hrs */
323#define VOL_STATS_TIME_IDX_4 4 /*1 day to 7 days */
324#define VOL_STATS_TIME_IDX_5 5 /*Greater than 1 week */
325
326/* Volume header. This is the contents of the named file representing
327 * the volume. Read-only by the file server!
328 */
329typedef struct VolumeHeader {
330 struct versionStamp stamp; /* Must be first field */
331 VolumeId id; /* Volume number */
332 VolumeId parent; /* Read-write volume number (or this volume
333 * number if this is a read-write volume) */
334 Inode volumeInfo;
335 Inode smallVnodeIndex;
336 Inode largeVnodeIndex;
337 Inode volumeAcl;
338 Inode volumeMountTable;
339 Inode linkTable;
340} VolumeHeader_t;
341
342
343typedef struct VolumeDiskHeader {
344 struct versionStamp stamp; /* Must be first field */
345 VolumeId id; /* Volume number */
346 VolumeId parent; /* Read-write volume number (or this volume
347 * number if this is a read-write volume) */
348 afs_int32 volumeInfo_lo;
349 afs_int32 smallVnodeIndex_lo;
350 afs_int32 largeVnodeIndex_lo;
351 afs_int32 volumeAcl_lo;
352 afs_int32 volumeMountTable_lo;
353 afs_int32 volumeInfo_hi;
354 afs_int32 smallVnodeIndex_hi;
355 afs_int32 largeVnodeIndex_hi;
356 afs_int32 volumeAcl_hi;
357 afs_int32 volumeMountTable_hi;
358 afs_int32 linkTable_lo;
359 afs_int32 linkTable_hi;
360 /* If you add fields, add them before here and reduce the size of array */
361 bit32 reserved[3];
362} VolumeDiskHeader_t;
363
364/* A vnode index file header */
365struct IndexFileHeader {
366 struct versionStamp stamp;
367};
368
369
370/******************************************************************************/
371/* Volume Data which is stored on disk and can also be maintained in memory. */
372/******************************************************************************/
373typedef struct VolumeDiskData {
374 struct versionStamp stamp; /* Must be first field */
375 VolumeId id; /* Volume id--unique over all systems */
376#define VNAMESIZE 32 /* including 0 byte */
377 char name[VNAMESIZE]; /* Unofficial name for the volume */
378 byte inUse; /* Volume is being used (perhaps it is online),
379 * or the system crashed while it was used */
380 byte inService; /* Volume in service, not necessarily on line
381 * This bit is set by an operator/system
382 * programmer. Manually taking a volume offline
383 * always clears the inService bit. Taking
384 * it out of service also takes it offline */
385 byte blessed; /* Volume is administratively blessed with
386 * the ability to go on line. Set by a system
387 * administrator. Clearing this bit will
388 * take the volume offline */
389 byte needsSalvaged; /* Volume needs salvaged--an unrecoverable
390 * error occured to the volume. Note: a volume
391 * may still require salvage even if this
392 * flag isn't set--e.g. if a system crash
393 * occurred while the volume was on line. */
394 bit32 uniquifier; /* Next vnode uniquifier for this volume */
395 int type; /* */
396 VolumeId parentId; /* Id of parent, if type==readonly */
397 VolumeId cloneId; /* Latest read-only clone, if type==readwrite,
398 * 0 if the volume has never been cloned. Note: the
399 * indicated volume does not necessarily exist (it
400 * may have been deleted since cloning). */
401 VolumeId backupId; /* Latest backup copy of this read write volume */
402 VolumeId restoredFromId; /* The id in the dump this volume was restored from--used simply
403 * to make sure that an incremental dump is not restored on top
404 * of something inappropriate: Note: this field itself is NEVER
405 * dumped!!! */
406 byte needsCallback; /* Set by the salvager if anything was changed
407 * about the volume. Note: this is not set by
408 * clone/makebackups when setting the copy-on-write
409 * flag in directories; this flag is not seen by
410 * the clients. */
411#define DESTROY_ME 0xD3
412 byte destroyMe; /* If this is set to DESTROY_ME, then the salvager should destroy
413 * this volume; it is bogus (left over from an aborted volume move,
414 * for example). Note: if this flag is on, then inService should
415 * be OFF--only the salvager checks this flag */
416#ifdef ALPHA_DUX40_ENV
417#define DONT_SALVAGE 0xE6
418#else /* ALPHA_DUX40_ENV */
419#define DONT_SALVAGE 0xE5
420#endif /* ALPHA_DUX40_ENV */
421 byte dontSalvage; /* If this is on, then don't bother salvaging this volume */
422 byte reserveb3;
423
424 bit32 reserved1[6];
425
426
427 /* Administrative stuff */
428 int maxquota; /* Quota maximum, 1K blocks */
429 int minquota; /* Quota minimum, 1K blocks */
430 int maxfiles; /* Maximum number of files (i.e. inodes) */
431 bit32 accountNumber; /* Uninterpreted account number */
432 bit32 owner; /* The person administratively responsible
433 * for this volume */
434 int reserved2[8]; /* Other administrative constraints */
435
436 /* Resource usage & statistics */
437 int filecount; /* Actual number of files */
438 int diskused; /* Actual disk space used, 1K blocks */
439 int dayUse; /* Metric for today's usage of this volume so far */
440 int weekUse[7]; /* Usage of the volume for the last week.
441 * weekUse[0] is for most recent complete 24 hour period
442 * of measurement; week[6] is 7 days ago */
443 Date dayUseDate; /* Date the dayUse statistics refer to; the week use stats
444 * are the preceding 7 days */
445 unsigned int volUpdateCounter; /*incremented at every update of volume*/
446 int reserved3[10]; /* Other stats here */
447
448 /* Server supplied dates */
449 Date creationDate; /* Creation date for a read/write
450 * volume; cloning date for original copy of
451 * a readonly volume (replicated volumes have
452 * the same creation date) */
453 Date accessDate; /* Last access time by a user, large granularity */
454 Date updateDate; /* Last modification by user or salvager */
455 Date expirationDate; /* 0 if it never expires */
456 Date backupDate; /* last time a backup clone was taken */
457
458 /* Time that this copy of this volume was made. NEVER backed up. This field is only
459 * set when the copy is created */
460 Date copyDate;
461
462 bit32 stat_initialized; /*Are the stat fields below set up? */
463 bit32 reserved4[7];
464
465 /* messages */
466#define VMSGSIZE 128
467 char offlineMessage[VMSGSIZE]; /* Why the volume is offline */
468#define VOL_STATS_BYTES 128
469 /*
470 * Keep per-volume aggregate statistics on type and distance of access,
471 * along with authorship info.
472 */
473 bit32 stat_reads[VOL_STATS_NUM_RWINFO_FIELDS];
474 bit32 stat_writes[VOL_STATS_NUM_RWINFO_FIELDS];
475 bit32 stat_fileSameAuthor[VOL_STATS_NUM_TIME_FIELDS];
476 bit32 stat_fileDiffAuthor[VOL_STATS_NUM_TIME_FIELDS];
477 bit32 stat_dirSameAuthor[VOL_STATS_NUM_TIME_FIELDS];
478 bit32 stat_dirDiffAuthor[VOL_STATS_NUM_TIME_FIELDS];
479
480} VolumeDiskData;
481
482
483/**************************************/
484/* Memory resident volume information */
485/**************************************/
486
487/**
488 * global volume package stats.
489 */
490typedef struct VolPkgStats {
491#ifdef AFS_DEMAND_ATTACH_FS
492 /*
493 * demand attach fs
494 * extended volume package statistics
495 */
496
497 /* levels */
498 afs_uint32 state_levels[VOL_STATE_COUNT]; /**< volume state transition counters */
499
500 /* counters */
501 afs_uint64 hash_looks; /**< number of hash chain element traversals */
502 afs_uint64 hash_reorders; /**< number of hash chain reorders */
503 afs_uint64 salvages; /**< online salvages since fileserver start */
504 afs_uint64 vol_ops; /**< volume operations since fileserver start */
505#endif /* AFS_DEMAND_ATTACH_FS */
506
507 afs_uint64 hdr_loads; /**< header loads from disk */
508 afs_uint64 hdr_gets; /**< header pulls out of LRU */
509 afs_uint64 attaches; /**< volume attaches since fileserver start */
510 afs_uint64 soft_detaches; /**< soft detach ops since fileserver start */
511
512 /* configuration parameters */
513 afs_uint32 hdr_cache_size; /**< size of volume header cache */
514} VolPkgStats;
515extern VolPkgStats VStats;
516
517/*
518 * volume header cache supporting structures
519 */
520struct volume_hdr_LRU_stats {
521 afs_uint32 free;
522 afs_uint32 used;
523 afs_uint32 attached;
524};
525
526struct volume_hdr_LRU_t {
527 struct rx_queue lru;
528 struct volume_hdr_LRU_stats stats;
529};
530extern struct volume_hdr_LRU_t volume_hdr_LRU;
531
532/*
533 * volume hash chain supporting structures
534 */
535typedef struct VolumeHashChainHead {
536 struct rx_queue queue;
537 int len;
538 /* someday we could put a per-chain lock here... */
539#ifdef AFS_DEMAND_ATTACH_FS
540 int busy;
541 int cacheCheck;
542
543 /* per-chain statistics */
544 afs_uint64 looks;
545 afs_uint64 gets;
546 afs_uint64 reorders;
547
548 pthread_cond_t chain_busy_cv;
549#endif /* AFS_DEMAND_ATTACH_FS */
550} VolumeHashChainHead;
551
552typedef struct VolumeHashTable {
553 int Size;
554 int Mask;
555 VolumeHashChainHead * Table;
556} VolumeHashTable_t;
557extern VolumeHashTable_t VolumeHashTable;
558
559struct VolumeHashChainStats {
560 afs_int32 table_size;
561 afs_int32 chain_len;
562#ifdef AFS_DEMAND_ATTACH_FS
563 afs_int32 chain_cacheCheck;
564 afs_int32 chain_busy;
565 afs_uint64 chain_looks;
566 afs_uint64 chain_gets;
567 afs_uint64 chain_reorders;
568#endif
569};
570
571
572#ifdef AFS_DEMAND_ATTACH_FS
573/**
574 * DAFS extended per-volume statistics.
575 *
576 * @note this data lives across the entire
577 * lifetime of the fileserver process
578 */
579typedef struct VolumeStats {
580 /* counters */
581 afs_uint64 hash_lookups; /**< hash table lookups */
582 afs_uint64 hash_short_circuits; /**< short circuited hash lookups (due to cacheCheck) */
583 afs_uint64 hdr_loads; /**< header loads from disk */
584 afs_uint64 hdr_gets; /**< header pulls out of LRU */
585 afs_uint16 attaches; /**< attaches of this volume since fileserver start */
586 afs_uint16 soft_detaches; /**< soft detaches of this volume */
587 afs_uint16 salvages; /**< online salvages since fileserver start */
588 afs_uint16 vol_ops; /**< volume operations since fileserver start */
589
590 /* timestamps */
591 afs_uint32 last_attach; /**< unix timestamp of last VAttach */
592 afs_uint32 last_get; /**< unix timestamp of last VGet/VHold */
593 afs_uint32 last_promote; /**< unix timestamp of last VLRU promote/demote */
594 afs_uint32 last_hdr_get; /**< unix timestamp of last GetVolumeHeader() */
595 afs_uint32 last_hdr_load; /**< unix timestamp of last LoadVolumeHeader() */
596 afs_uint32 last_salvage; /**< unix timestamp of last initiation of an online salvage */
597 afs_uint32 last_salvage_req; /**< unix timestamp of last SALVSYNC request */
598 afs_uint32 last_vol_op; /**< unix timestamp of last volume operation */
599} VolumeStats;
600
601
602#define SALVAGE_PRIO_UPDATE_INTERVAL 3 /**< number of seconds between prio updates */
603#define SALVAGE_COUNT_MAX 16 /**< number of online salvages we
604 * allow before moving the volume
605 * into a permanent error state
606 *
607 * once this threshold is reached,
608 * the operator will have to manually
609 * issue a 'bos salvage' to bring
610 * the volume back online
611 */
612
613/**
614 * DAFS online salvager state.
615 */
616typedef struct VolumeOnlineSalvage {
617 afs_uint32 prio; /**< number of VGetVolume's since salvage requested */
618 int reason; /**< reason for requesting online salvage */
619 byte requested; /**< flag specifying that salvage should be scheduled */
620 byte scheduled; /**< flag specifying whether online salvage scheduled */
621 byte scheduling; /**< if nonzero, this volume has entered
622 * VCheckSalvage(), so if we recurse into
623 * VCheckSalvage() with this set, exit immediately
624 * to avoid recursing forever */
625 byte reserved[1]; /**< padding */
626} VolumeOnlineSalvage;
627
628/**
629 * DAFS Volume LRU state.
630 */
631typedef struct VolumeVLRUState {
632 struct rx_queue lru; /**< VLRU queue for this generation */
633 VLRUQueueName idx; /**< VLRU generation index */
634} VolumeVLRUState;
635#endif /* AFS_DEMAND_ATTACH_FS */
636
637/**
638 * node for a volume's rx_call_list.
639 */
640struct VCallByVol {
641 struct rx_queue q;
642 struct rx_call *call;
643};
644
645typedef struct Volume {
646 struct rx_queue q; /* Volume hash chain pointers */
647 VolumeId hashid; /* Volume number -- for hash table lookup */
648 struct volHeader *header; /* Cached disk data */
649 Device device; /* Unix device for the volume */
650 struct DiskPartition64
651 *partition; /* Information about the Unix partition */
652 struct vnodeIndex {
653 IHandle_t *handle; /* Unix inode holding this index */
654 byte *bitmap; /* Index bitmap */
655 afs_uint32 bitmapSize; /* length of bitmap, in bytes */
656 afs_uint32 bitmapOffset; /* Which byte address of the first long to
657 * start search from in bitmap */
658 } vnodeIndex[nVNODECLASSES];
659 IHandle_t *linkHandle;
660 Unique nextVnodeUnique; /* Derived originally from volume uniquifier.
661 * This is the actual next version number to
662 * assign; the uniquifier is bumped by 200 and
663 * and written to disk every 200 file creates
664 * If the volume is shutdown gracefully, the
665 * uniquifier should be rewritten with the
666 * value nextVnodeVersion */
667 IHandle_t *diskDataHandle; /* Unix inode holding general volume info */
668 byte shuttingDown; /* This volume is going to be detached */
669 byte goingOffline; /* This volume is going offline */
670 bit32 cacheCheck; /* Online sequence number to be used to invalidate vnode cache entries
671 * that stayed around while a volume was offline */
672 short nUsers; /* Number of users of this volume header */
673#define VOL_PUTBACK 1
674#define VOL_PUTBACK_DELETE 2
675 byte needsPutBack; /* For a volume utility, this flag is set to VOL_PUTBACK if we
676 * need to give the volume back when we detach it. The server has
677 * certain modes where it doesn't detach the volume, and
678 * if we give it back spuriously, the server aborts. If set to
679 * VOL_PUTBACK_DELETE, it indicates that we need to tell the
680 * fileserver that the volume is gone entirely, instead of just
681 * giving the volume back to the fileserver. This field
682 * is meaningless on the file server */
683 byte specialStatus; /* An error code to return on VGetVolume: the
684 * volume is unavailable for the reason quoted,
685 * currently VBUSY or VMOVED */
686 afs_uint32 checkoutMode; /* for volume utilities, mode number for current checkout */
687 afs_uint32 updateTime; /* Time that this volume was put on the updated
688 * volume list--the list of volumes that will be
689 * salvaged should the file server crash */
690 struct rx_queue vnode_list; /**< linked list of cached vnodes for this volume */
691 struct rx_queue rx_call_list; /**< linked list of split RX calls using this
692 * volume (fileserver only) */
693#ifdef AFS_DEMAND_ATTACH_FS
694 VolState attach_state; /* what stage of attachment has been completed */
695 afs_uint32 attach_flags; /* flags related to attachment state */
696 pthread_cond_t attach_cv; /* state change condition variable */
697 short nWaiters; /* volume package internal ref count */
698 int chainCacheCheck; /* Volume hash chain cache check */
699 struct rx_queue vol_list; /* per-partition volume list (VByPList) */
700
701 VolumeOnlineSalvage salvage; /* online salvager state */
702 VolumeStats stats; /* per-volume statistics */
703 VolumeVLRUState vlru; /* state specific to the VLRU */
704 FSSYNC_VolOp_info * pending_vol_op; /* fssync command info for any pending vol ops */
705#endif /* AFS_DEMAND_ATTACH_FS */
706 int usage_bumps_outstanding; /**< to rate limit the usage update i/o by accesses */
707 int usage_bumps_next_write; /**< to rate limit the usage update i/o by time */
708} Volume;
709
710struct volHeader {
711 struct rx_queue lru;
712 VolumeDiskData diskstuff; /* General volume info read from disk */
713 Volume *back; /* back pointer to current volume structure */
714};
715
716/* These macros are used to export fields within the volume header. This was added
717 to facilitate changing the actual representation */
718
719#define V_device(vp) ((vp)->device)
720#define V_partition(vp) ((vp)->partition)
721#define V_diskDataHandle(vp) ((vp)->diskDataHandle)
722#define V_vnodeIndex(vp) ((vp)->vnodeIndex)
723#define V_nextVnodeUnique(vp) ((vp)->nextVnodeUnique)
724#define V_linkHandle(vp) ((vp)->linkHandle)
725#define V_checkoutMode(vp) ((vp)->checkoutMode)
726#ifdef AFS_DEMAND_ATTACH_FS
727#define V_attachState(vp) ((vp)->attach_state)
728#define V_attachFlags(vp) ((vp)->attach_flags)
729#define V_attachCV(vp) ((vp)->attach_cv)
730#endif /* AFS_DEMAND_ATTACH_FS */
731
732/* N.B. V_id must be this, rather than vp->id, or some programs will break, probably */
733#define V_stamp(vp) ((vp)->header->diskstuff.stamp)
734#define V_id(vp) ((vp)->header->diskstuff.id)
735#define V_name(vp) ((vp)->header->diskstuff.name)
736#define V_inUse(vp) ((vp)->header->diskstuff.inUse)
737#define V_inService(vp) ((vp)->header->diskstuff.inService)
738#define V_blessed(vp) ((vp)->header->diskstuff.blessed)
739#define V_needsSalvaged(vp) ((vp)->header->diskstuff.needsSalvaged)
740#define V_uniquifier(vp) ((vp)->header->diskstuff.uniquifier)
741#define V_type(vp) ((vp)->header->diskstuff.type)
742#define V_parentId(vp) ((vp)->header->diskstuff.parentId)
743#define V_cloneId(vp) ((vp)->header->diskstuff.cloneId)
744#define V_backupId(vp) ((vp)->header->diskstuff.backupId)
745#define V_restoredFromId(vp) ((vp)->header->diskstuff.restoredFromId)
746#define V_needsCallback(vp) ((vp)->header->diskstuff.needsCallback)
747#define V_destroyMe(vp) ((vp)->header->diskstuff.destroyMe)
748#define V_dontSalvage(vp) ((vp)->header->diskstuff.dontSalvage)
749#define V_maxquota(vp) ((vp)->header->diskstuff.maxquota)
750#define V_minquota(vp) ((vp)->header->diskstuff.minquota)
751#define V_maxfiles(vp) ((vp)->header->diskstuff.maxfiles)
752#define V_accountNumber(vp) ((vp)->header->diskstuff.accountNumber)
753#define V_owner(vp) ((vp)->header->diskstuff.owner)
754#define V_filecount(vp) ((vp)->header->diskstuff.filecount)
755#define V_diskused(vp) ((vp)->header->diskstuff.diskused)
756#define V_dayUse(vp) ((vp)->header->diskstuff.dayUse)
757#define V_weekUse(vp) ((vp)->header->diskstuff.weekUse)
758#define V_dayUseDate(vp) ((vp)->header->diskstuff.dayUseDate)
759#define V_creationDate(vp) ((vp)->header->diskstuff.creationDate)
760#define V_accessDate(vp) ((vp)->header->diskstuff.accessDate)
761#define V_updateDate(vp) ((vp)->header->diskstuff.updateDate)
762#define V_expirationDate(vp) ((vp)->header->diskstuff.expirationDate)
763#define V_backupDate(vp) ((vp)->header->diskstuff.backupDate)
764#define V_copyDate(vp) ((vp)->header->diskstuff.copyDate)
765#define V_offlineMessage(vp) ((vp)->header->diskstuff.offlineMessage)
766#define V_disk(vp) ((vp)->header->diskstuff)
767#define V_motd(vp) ((vp)->header->diskstuff.motd)
768#define V_stat_initialized(vp) ((vp)->header->diskstuff.stat_initialized)
769#define V_stat_area(vp) (((vp)->header->diskstuff.stat_reads))
770#define V_stat_reads(vp, idx) (((vp)->header->diskstuff.stat_reads)[idx])
771#define V_stat_writes(vp, idx) (((vp)->header->diskstuff.stat_writes)[idx])
772#define V_stat_fileSameAuthor(vp, idx) (((vp)->header->diskstuff.stat_fileSameAuthor)[idx])
773#define V_stat_fileDiffAuthor(vp, idx) (((vp)->header->diskstuff.stat_fileDiffAuthor)[idx])
774#define V_stat_dirSameAuthor(vp, idx) (((vp)->header->diskstuff.stat_dirSameAuthor)[idx])
775#define V_stat_dirDiffAuthor(vp, idx) (((vp)->header->diskstuff.stat_dirDiffAuthor)[idx])
776#define V_volUpdateCounter(vp) ((vp)->header->diskstuff.volUpdateCounter)
777
778/* File offset computations. The offset values in the volume header are
779 computed with these macros -- when the file is written only!! */
780#define VOLUME_MOUNT_TABLE_OFFSET(Volume) (sizeof (VolumeDiskData))
781#define VOLUME_BITMAP_OFFSET(Volume) \
782 (sizeof (VolumeDiskData) + (Volume)->disk.mountTableSize)
783
784
785extern char *VSalvageMessage; /* Canonical message when a volume is forced
786 * offline */
787extern Volume *VGetVolume(Error * ec, Error * client_ec, VolumeId volumeId);
788extern Volume *VGetVolumeWithCall(Error * ec, Error * client_ec, VolumeId volumeId,
789 const struct timespec *ts, struct VCallByVol *cbv);
790extern Volume *VGetVolume_r(Error * ec, VolumeId volumeId);
791extern void VPutVolume(Volume *);
792extern void VPutVolumeWithCall(Volume *vp, struct VCallByVol *cbv);
793extern void VPutVolume_r(Volume *);
794extern void VOffline(Volume * vp, char *message);
795extern void VOffline_r(Volume * vp, char *message);
796extern int VConnectFS(void);
797extern int VConnectFS_r(void);
798extern void VDisconnectFS(void);
799extern void VDisconnectFS_r(void);
800extern int VChildProcReconnectFS(void);
801extern Volume *VAttachVolume(Error * ec, VolumeId volumeId, int mode);
802extern Volume *VAttachVolume_r(Error * ec, VolumeId volumeId, int mode);
803extern Volume *VCreateVolume(Error * ec, char *partname, VolumeId volumeId,
804 VolumeId parentId);
805extern Volume *VCreateVolume_r(Error * ec, char *partname, VolumeId volumeId,
806 VolumeId parentId);
807extern void VGrowBitmap(struct vnodeIndex *index);
808extern int VAllocBitmapEntry(Error * ec, Volume * vp,
809 struct vnodeIndex *index);
810extern int VAllocBitmapEntry_r(Error * ec, Volume * vp,
811 struct vnodeIndex *index, int flags);
812extern void VFreeBitMapEntry(Error * ec, Volume *vp, struct vnodeIndex *index,
813 unsigned bitNumber);
814extern void VFreeBitMapEntry_r(Error * ec, Volume *vp, struct vnodeIndex *index,
815 unsigned bitNumber, int flags);
816extern int VolumeNumber(char *name);
817extern char *VolumeExternalName(VolumeId volumeId);
818extern int VolumeExternalName_r(VolumeId volumeId, char *name, size_t len);
819extern Volume *VAttachVolumeByName(Error * ec, char *partition, char *name,
820 int mode);
821extern Volume *VAttachVolumeByName_r(Error * ec, char *partition, char *name,
822 int mode);
823extern void VShutdown(void);
824extern void VSetTranquil(void);
825extern void VUpdateVolume(Error * ec, Volume * vp);
826extern void VUpdateVolume_r(Error * ec, Volume * vp, int flags);
827extern void VAddToVolumeUpdateList(Error * ec, Volume * vp);
828extern void VAddToVolumeUpdateList_r(Error * ec, Volume * vp);
829extern void VDetachVolume(Error * ec, Volume * vp);
830extern void VDetachVolume_r(Error * ec, Volume * vp);
831extern void VForceOffline(Volume * vp);
832extern void VForceOffline_r(Volume * vp, int flags);
833extern void VBumpVolumeUsage(Volume * vp);
834extern void VBumpVolumeUsage_r(Volume * vp);
835extern void VSetDiskUsage(void);
836extern void VPrintCacheStats(void);
837extern void VReleaseVnodeFiles_r(Volume * vp);
838extern void VCloseVnodeFiles_r(Volume * vp);
839extern struct DiskPartition64 *VGetPartition(char *name, int abortp);
840extern struct DiskPartition64 *VGetPartition_r(char *name, int abortp);
841extern void VOptDefaults(ProgramType pt, VolumePackageOptions * opts);
842extern int VInitVolumePackage2(ProgramType pt, VolumePackageOptions * opts);
843extern int VInitAttachVolumes(ProgramType pt);
844extern void DiskToVolumeHeader(VolumeHeader_t * h, VolumeDiskHeader_t * dh);
845extern void VolumeHeaderToDisk(VolumeDiskHeader_t * dh, VolumeHeader_t * h);
846extern void AssignVolumeName(VolumeDiskData * vol, char *name, char *ext);
847extern void VTakeOffline_r(Volume * vp);
848extern void VTakeOffline(Volume * vp);
849extern Volume * VLookupVolume_r(Error * ec, VolumeId volumeId, Volume * hint);
850extern void VGetVolumePath(Error * ec, VolumeId volumeId, char **partitionp,
851 char **namep);
852extern char *vol_DevName(dev_t adev, char *wpath);
853extern afs_int32 VIsGoingOffline(struct Volume *vp);
854
855struct VLockFile;
856extern void VLockFileInit(struct VLockFile *lf, const char *path);
857extern void VLockFileReinit(struct VLockFile *lf);
858extern int VLockFileLock(struct VLockFile *lf, afs_uint32 offset,
859 int locktype, int nonblock);
860extern void VLockFileUnlock(struct VLockFile *lf, afs_uint32 offset);
861
862extern int VSetVolHashSize(int logsize);
863
864#ifdef AFS_DEMAND_ATTACH_FS
865extern Volume *VPreAttachVolumeByName(Error * ec, char *partition, char *name);
866extern Volume *VPreAttachVolumeByName_r(Error * ec, char *partition, char *name);
867extern Volume *VPreAttachVolumeById_r(Error * ec, char * partition,
868 VolumeId volumeId);
869extern Volume *VPreAttachVolumeByVp_r(Error * ec, struct DiskPartition64 * partp,
870 Volume * vp, VolumeId volume_id);
871extern Volume *VGetVolumeByVp_r(Error * ec, Volume * vp);
872extern int VShutdownByPartition_r(struct DiskPartition64 * dp);
873extern int VShutdownVolume_r(Volume * vp);
874extern int VConnectSALV(void);
875extern int VConnectSALV_r(void);
876extern int VReconnectSALV(void);
877extern int VReconnectSALV_r(void);
878extern int VDisconnectSALV(void);
879extern int VDisconnectSALV_r(void);
880extern void VPrintExtendedCacheStats(int flags);
881extern void VPrintExtendedCacheStats_r(int flags);
882extern void VLRU_SetOptions(int option, afs_uint32 val);
883extern int VRequestSalvage_r(Error * ec, Volume * vp, int reason, int flags);
884extern int VUpdateSalvagePriority_r(Volume * vp);
885extern int VRegisterVolOp_r(Volume * vp, FSSYNC_VolOp_info * vopinfo);
886extern int VDeregisterVolOp_r(Volume * vp);
887extern void VCancelReservation_r(Volume * vp);
888extern int VChildProcReconnectFS_r(void);
889extern void VOfflineForVolOp_r(Error *ec, Volume *vp, char *message);
890#endif /* AFS_DEMAND_ATTACH_FS */
891
892#ifdef AFS_DEMAND_ATTACH_FS
893struct VDiskLock;
894extern void VDiskLockInit(struct VDiskLock *dl, struct VLockFile *lf,
895 afs_uint32 offset);
896extern int VGetDiskLock(struct VDiskLock *dl, int locktype, int nonblock);
897extern void VReleaseDiskLock(struct VDiskLock *dl, int locktype);
898#endif /* AFS_DEMAND_ATTACH_FS */
899extern int VVolOpLeaveOnline_r(Volume * vp, FSSYNC_VolOp_info * vopinfo);
900extern int VVolOpLeaveOnlineNoHeader_r(Volume * vp, FSSYNC_VolOp_info * vopinfo);
901extern int VVolOpSetVBusy_r(Volume * vp, FSSYNC_VolOp_info * vopinfo);
902
903extern void VPurgeVolume(Error * ec, Volume * vp);
904
905extern afs_int32 VCanScheduleSalvage(void);
906extern afs_int32 VCanUseFSSYNC(void);
907extern afs_int32 VCanUseSALVSYNC(void);
908extern afs_int32 VCanUnsafeAttach(void);
909extern afs_int32 VReadVolumeDiskHeader(VolumeId volid,
910 struct DiskPartition64 * dp,
911 VolumeDiskHeader_t * hdr);
912extern afs_int32 VWriteVolumeDiskHeader(VolumeDiskHeader_t * hdr,
913 struct DiskPartition64 * dp);
914extern afs_int32 VCreateVolumeDiskHeader(VolumeDiskHeader_t * hdr,
915 struct DiskPartition64 * dp);
916extern afs_int32 VDestroyVolumeDiskHeader(struct DiskPartition64 * dp,
917 VolumeId volid, VolumeId parent);
918
919/**
920 * VWalkVolumeHeaders header callback.
921 *
922 * @param[in] dp disk partition
923 * @param[in] name full path to the .vol header file
924 * @param[in] hdr the header data that was read from the .vol header
925 * @param[in] last 1 if this is the last attempt to read the vol header, 0
926 * otherwise. DAFS VWalkVolumeHeaders will retry reading the
927 * header once, if a non-fatal error occurs when reading the
928 * header, or if this function returns a positive error code.
929 * So, if there is a problem, this function will be called
930 * first with last=0, then with last=1, then the error function
931 * callback will be called. For non-DAFS, this is always 1.
932 * @param[in] rock the rock passed to VWalkVolumeHeaders
933 *
934 * @return operation status
935 * @retval 0 success
936 * @retval negative a fatal error that should stop the walk immediately
937 * @retval positive an error with the volume header was encountered; the walk
938 * should continue, but the error function should be called on this
939 * header
940 *
941 * @see VWalkVolumeHeaders
942 */
943typedef int (*VWalkVolFunc)(struct DiskPartition64 *dp, const char *name,
944 struct VolumeDiskHeader *hdr, int last,
945 void *rock);
946/**
947 * VWalkVolumeHeaders error callback.
948 *
949 * This is called from VWalkVolumeHeaders when an invalid or otherwise
950 * problematic volume header is encountered. It is typically implemented as a
951 * wrapper to unlink the .vol file.
952 *
953 * @param[in] dp disk partition
954 * @param[in] name full path to the .vol header file
955 * @param[in] hdr header read in from the .vol file, or NULL if it could not
956 * be read
957 * @param[in] rock rock passed to VWalkVolumeHeaders
958 *
959 * @see VWalkVolumeHeaders
960 */
961typedef void (*VWalkErrFunc)(struct DiskPartition64 *dp, const char *name,
962 struct VolumeDiskHeader *hdr, void *rock);
963extern int VWalkVolumeHeaders(struct DiskPartition64 *dp, const char *partpath,
964 VWalkVolFunc volfunc, VWalkErrFunc errfunc,
965 void *rock);
966
967/* Naive formula relating number of file size to number of 1K blocks in file */
968/* Note: we charge 1 block for 0 length files so the user can't store
969 an inifite number of them; for most files, we give him the inode, vnode,
970 and indirect block overhead, for FREE! */
971#define nBlocks(bytes) ((afs_sfsize_t)((bytes) == 0? 1: (((afs_sfsize_t)(bytes))+1023)/1024))
972
973/* Client process id -- file server sends a Check volumes signal back to the client at this pid */
974#define CLIENTPID "/vice/vol/clientpid"
975
976/* Modes of attachment, for VAttachVolume[ByName] to convey to the file server */
977#define V_READONLY 1 /* Absolutely no updates will be done to the volume */
978#define V_CLONE 2 /* Cloning the volume: if it is read/write, then directory
979 * version numbers will change. Header will be updated. If
980 * the volume is read-only, the file server may continue to
981 * server it; it may also continue to server it in read/write
982 * mode if the writes are deferred */
983#define V_VOLUPD 3 /* General update or volume purge is possible. Volume must
984 * go offline */
985#define V_DUMP 4 /* A dump of the volume is requested; the volume can be served
986 * read-only during this time */
987#define V_SECRETLY 5 /* Secret attach of the volume. This is used to attach a volume
988 * which the file server doesn't know about--and which it shouldn't
989 * know about yet, since the volume has just been created and
990 * is somewhat bogus. Required to make sure that a file server
991 * never knows about more than one copy of the same volume--when
992 * a volume is moved from one partition to another on a single
993 * server */
994#define V_PEEK 6 /* "Peek" at the volume without telling the fileserver. This is
995 * similar to V_SECRETLY, but read-only. It is used in cases where
996 * not impacting fileserver performance is more important than
997 * getting the most recent data. */
998
999
1000
1001/* VUpdateVolume_r flags */
1002#define VOL_UPDATE_WAIT 0x1 /* for demand attach, wait for other exclusive ops to end */
1003#define VOL_UPDATE_NOFORCEOFF 0x2 /* don't force offline on failure. this is to prevent
1004 * infinite recursion between vupdate and vforceoff */
1005
1006/* VForceOffline_r flags */
1007#define VOL_FORCEOFF_NOUPDATE 0x1 /* don't force update on forceoff. this is to prevent
1008 * infinite recursion between vupdate and vforceoff */
1009
1010/* VSyncVolume_r flags */
1011#define VOL_SYNC_WAIT 0x1 /* for demand attach, wait for other exclusive ops to end */
1012
1013/* VAllocBitmapEntry_r flags */
1014#define VOL_ALLOC_BITMAP_WAIT 0x1 /* for demand attach, wait for other exclusive ops to end */
1015
1016/* VFreeBitMapEntry_r flags */
1017#define VOL_FREE_BITMAP_WAIT 0x1 /* for demand attach, wait for other exclusive ops to end */
1018
1019/* VRequestSalvage_r flags */
1020#define VOL_SALVAGE_NO_OFFLINE 0x1 /* we do not need to wait to offline the volume; it has
1021 * not been fully attached */
1022
1023#define VOLUME_BITMAP_GROWSIZE 16 /* bytes, => 128vnodes */
1024 /* Must be a multiple of 4 (1 word) !! */
1025
1026#if defined(NEARINODE_HINT)
1027#define V_pref(vp,nearInode) nearInodeHash(V_id(vp),(nearInode)); (nearInode) %= V_partition(vp)->f_files
1028#else
1029#define V_pref(vp,nearInode) nearInode = 0
1030#endif /* NEARINODE_HINT */
1031
1032hdr_static_inline(unsigned long)
1033afs_printable_VolumeId_lu(VolumeId d) { return (unsigned long) (d); }
1034
1035hdr_static_inline(unsigned int)
1036afs_printable_VnodeId_u(VnodeId d) { return (unsigned int) d; }
1037
1038#endif /* __volume_h */