Commit | Line | Data |
---|---|---|
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) | |
27 | typedef 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> | |
66 | extern pthread_mutex_t vol_glock_mutex; | |
67 | extern pthread_mutex_t vol_trans_mutex; | |
68 | extern pthread_cond_t vol_put_volume_cond; | |
69 | extern pthread_cond_t vol_sleep_cond; | |
70 | extern pthread_cond_t vol_vinit_cond; | |
71 | extern ih_init_params vol_io_params; | |
72 | extern int vol_attach_threads; | |
73 | #ifdef VOL_LOCK_DEBUG | |
74 | extern 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 | */ | |
115 | typedef 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; | |
124 | extern ProgramType programType; /* The type of program using the package */ | |
125 | ||
126 | /* Some initialization parameters for the volume package */ | |
127 | /* Add new initialization parameters here */ | |
128 | extern int (*V_BreakVolumeCallbacks) (VolumeId); | |
129 | extern 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 | ||
142 | struct 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 | */ | |
154 | typedef 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 | */ | |
189 | enum 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 | */ | |
215 | typedef 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 | */ | |
234 | typedef struct VThreadOptions { | |
235 | int disallow_salvsync; /**< whether or not salvsync calls are allowed | |
236 | * on this thread (deadlock prevention). */ | |
237 | } VThreadOptions_t; | |
238 | extern pthread_key_t VThread_key; | |
239 | extern VThreadOptions_t VThread_defaults; | |
240 | ||
241 | #endif /* AFS_DEMAND_ATTACH_FS */ | |
242 | ||
243 | typedef 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 | */ | |
329 | typedef 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 | ||
343 | typedef 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 */ | |
365 | struct 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 | /******************************************************************************/ | |
373 | typedef 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 | */ | |
490 | typedef 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; | |
515 | extern VolPkgStats VStats; | |
516 | ||
517 | /* | |
518 | * volume header cache supporting structures | |
519 | */ | |
520 | struct volume_hdr_LRU_stats { | |
521 | afs_uint32 free; | |
522 | afs_uint32 used; | |
523 | afs_uint32 attached; | |
524 | }; | |
525 | ||
526 | struct volume_hdr_LRU_t { | |
527 | struct rx_queue lru; | |
528 | struct volume_hdr_LRU_stats stats; | |
529 | }; | |
530 | extern struct volume_hdr_LRU_t volume_hdr_LRU; | |
531 | ||
532 | /* | |
533 | * volume hash chain supporting structures | |
534 | */ | |
535 | typedef 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 | ||
552 | typedef struct VolumeHashTable { | |
553 | int Size; | |
554 | int Mask; | |
555 | VolumeHashChainHead * Table; | |
556 | } VolumeHashTable_t; | |
557 | extern VolumeHashTable_t VolumeHashTable; | |
558 | ||
559 | struct 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 | */ | |
579 | typedef 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 | */ | |
616 | typedef 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 | */ | |
631 | typedef 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 | */ | |
640 | struct VCallByVol { | |
641 | struct rx_queue q; | |
642 | struct rx_call *call; | |
643 | }; | |
644 | ||
645 | typedef 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 | ||
710 | struct 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 | ||
785 | extern char *VSalvageMessage; /* Canonical message when a volume is forced | |
786 | * offline */ | |
787 | extern Volume *VGetVolume(Error * ec, Error * client_ec, VolumeId volumeId); | |
788 | extern Volume *VGetVolumeWithCall(Error * ec, Error * client_ec, VolumeId volumeId, | |
789 | const struct timespec *ts, struct VCallByVol *cbv); | |
790 | extern Volume *VGetVolume_r(Error * ec, VolumeId volumeId); | |
791 | extern void VPutVolume(Volume *); | |
792 | extern void VPutVolumeWithCall(Volume *vp, struct VCallByVol *cbv); | |
793 | extern void VPutVolume_r(Volume *); | |
794 | extern void VOffline(Volume * vp, char *message); | |
795 | extern void VOffline_r(Volume * vp, char *message); | |
796 | extern int VConnectFS(void); | |
797 | extern int VConnectFS_r(void); | |
798 | extern void VDisconnectFS(void); | |
799 | extern void VDisconnectFS_r(void); | |
800 | extern int VChildProcReconnectFS(void); | |
801 | extern Volume *VAttachVolume(Error * ec, VolumeId volumeId, int mode); | |
802 | extern Volume *VAttachVolume_r(Error * ec, VolumeId volumeId, int mode); | |
803 | extern Volume *VCreateVolume(Error * ec, char *partname, VolumeId volumeId, | |
804 | VolumeId parentId); | |
805 | extern Volume *VCreateVolume_r(Error * ec, char *partname, VolumeId volumeId, | |
806 | VolumeId parentId); | |
807 | extern void VGrowBitmap(struct vnodeIndex *index); | |
808 | extern int VAllocBitmapEntry(Error * ec, Volume * vp, | |
809 | struct vnodeIndex *index); | |
810 | extern int VAllocBitmapEntry_r(Error * ec, Volume * vp, | |
811 | struct vnodeIndex *index, int flags); | |
812 | extern void VFreeBitMapEntry(Error * ec, Volume *vp, struct vnodeIndex *index, | |
813 | unsigned bitNumber); | |
814 | extern void VFreeBitMapEntry_r(Error * ec, Volume *vp, struct vnodeIndex *index, | |
815 | unsigned bitNumber, int flags); | |
816 | extern int VolumeNumber(char *name); | |
817 | extern char *VolumeExternalName(VolumeId volumeId); | |
818 | extern int VolumeExternalName_r(VolumeId volumeId, char *name, size_t len); | |
819 | extern Volume *VAttachVolumeByName(Error * ec, char *partition, char *name, | |
820 | int mode); | |
821 | extern Volume *VAttachVolumeByName_r(Error * ec, char *partition, char *name, | |
822 | int mode); | |
823 | extern void VShutdown(void); | |
824 | extern void VSetTranquil(void); | |
825 | extern void VUpdateVolume(Error * ec, Volume * vp); | |
826 | extern void VUpdateVolume_r(Error * ec, Volume * vp, int flags); | |
827 | extern void VAddToVolumeUpdateList(Error * ec, Volume * vp); | |
828 | extern void VAddToVolumeUpdateList_r(Error * ec, Volume * vp); | |
829 | extern void VDetachVolume(Error * ec, Volume * vp); | |
830 | extern void VDetachVolume_r(Error * ec, Volume * vp); | |
831 | extern void VForceOffline(Volume * vp); | |
832 | extern void VForceOffline_r(Volume * vp, int flags); | |
833 | extern void VBumpVolumeUsage(Volume * vp); | |
834 | extern void VBumpVolumeUsage_r(Volume * vp); | |
835 | extern void VSetDiskUsage(void); | |
836 | extern void VPrintCacheStats(void); | |
837 | extern void VReleaseVnodeFiles_r(Volume * vp); | |
838 | extern void VCloseVnodeFiles_r(Volume * vp); | |
839 | extern struct DiskPartition64 *VGetPartition(char *name, int abortp); | |
840 | extern struct DiskPartition64 *VGetPartition_r(char *name, int abortp); | |
841 | extern void VOptDefaults(ProgramType pt, VolumePackageOptions * opts); | |
842 | extern int VInitVolumePackage2(ProgramType pt, VolumePackageOptions * opts); | |
843 | extern int VInitAttachVolumes(ProgramType pt); | |
844 | extern void DiskToVolumeHeader(VolumeHeader_t * h, VolumeDiskHeader_t * dh); | |
845 | extern void VolumeHeaderToDisk(VolumeDiskHeader_t * dh, VolumeHeader_t * h); | |
846 | extern void AssignVolumeName(VolumeDiskData * vol, char *name, char *ext); | |
847 | extern void VTakeOffline_r(Volume * vp); | |
848 | extern void VTakeOffline(Volume * vp); | |
849 | extern Volume * VLookupVolume_r(Error * ec, VolumeId volumeId, Volume * hint); | |
850 | extern void VGetVolumePath(Error * ec, VolumeId volumeId, char **partitionp, | |
851 | char **namep); | |
852 | extern char *vol_DevName(dev_t adev, char *wpath); | |
853 | extern afs_int32 VIsGoingOffline(struct Volume *vp); | |
854 | ||
855 | struct VLockFile; | |
856 | extern void VLockFileInit(struct VLockFile *lf, const char *path); | |
857 | extern void VLockFileReinit(struct VLockFile *lf); | |
858 | extern int VLockFileLock(struct VLockFile *lf, afs_uint32 offset, | |
859 | int locktype, int nonblock); | |
860 | extern void VLockFileUnlock(struct VLockFile *lf, afs_uint32 offset); | |
861 | ||
862 | extern int VSetVolHashSize(int logsize); | |
863 | ||
864 | #ifdef AFS_DEMAND_ATTACH_FS | |
865 | extern Volume *VPreAttachVolumeByName(Error * ec, char *partition, char *name); | |
866 | extern Volume *VPreAttachVolumeByName_r(Error * ec, char *partition, char *name); | |
867 | extern Volume *VPreAttachVolumeById_r(Error * ec, char * partition, | |
868 | VolumeId volumeId); | |
869 | extern Volume *VPreAttachVolumeByVp_r(Error * ec, struct DiskPartition64 * partp, | |
870 | Volume * vp, VolumeId volume_id); | |
871 | extern Volume *VGetVolumeByVp_r(Error * ec, Volume * vp); | |
872 | extern int VShutdownByPartition_r(struct DiskPartition64 * dp); | |
873 | extern int VShutdownVolume_r(Volume * vp); | |
874 | extern int VConnectSALV(void); | |
875 | extern int VConnectSALV_r(void); | |
876 | extern int VReconnectSALV(void); | |
877 | extern int VReconnectSALV_r(void); | |
878 | extern int VDisconnectSALV(void); | |
879 | extern int VDisconnectSALV_r(void); | |
880 | extern void VPrintExtendedCacheStats(int flags); | |
881 | extern void VPrintExtendedCacheStats_r(int flags); | |
882 | extern void VLRU_SetOptions(int option, afs_uint32 val); | |
883 | extern int VRequestSalvage_r(Error * ec, Volume * vp, int reason, int flags); | |
884 | extern int VUpdateSalvagePriority_r(Volume * vp); | |
885 | extern int VRegisterVolOp_r(Volume * vp, FSSYNC_VolOp_info * vopinfo); | |
886 | extern int VDeregisterVolOp_r(Volume * vp); | |
887 | extern void VCancelReservation_r(Volume * vp); | |
888 | extern int VChildProcReconnectFS_r(void); | |
889 | extern void VOfflineForVolOp_r(Error *ec, Volume *vp, char *message); | |
890 | #endif /* AFS_DEMAND_ATTACH_FS */ | |
891 | ||
892 | #ifdef AFS_DEMAND_ATTACH_FS | |
893 | struct VDiskLock; | |
894 | extern void VDiskLockInit(struct VDiskLock *dl, struct VLockFile *lf, | |
895 | afs_uint32 offset); | |
896 | extern int VGetDiskLock(struct VDiskLock *dl, int locktype, int nonblock); | |
897 | extern void VReleaseDiskLock(struct VDiskLock *dl, int locktype); | |
898 | #endif /* AFS_DEMAND_ATTACH_FS */ | |
899 | extern int VVolOpLeaveOnline_r(Volume * vp, FSSYNC_VolOp_info * vopinfo); | |
900 | extern int VVolOpLeaveOnlineNoHeader_r(Volume * vp, FSSYNC_VolOp_info * vopinfo); | |
901 | extern int VVolOpSetVBusy_r(Volume * vp, FSSYNC_VolOp_info * vopinfo); | |
902 | ||
903 | extern void VPurgeVolume(Error * ec, Volume * vp); | |
904 | ||
905 | extern afs_int32 VCanScheduleSalvage(void); | |
906 | extern afs_int32 VCanUseFSSYNC(void); | |
907 | extern afs_int32 VCanUseSALVSYNC(void); | |
908 | extern afs_int32 VCanUnsafeAttach(void); | |
909 | extern afs_int32 VReadVolumeDiskHeader(VolumeId volid, | |
910 | struct DiskPartition64 * dp, | |
911 | VolumeDiskHeader_t * hdr); | |
912 | extern afs_int32 VWriteVolumeDiskHeader(VolumeDiskHeader_t * hdr, | |
913 | struct DiskPartition64 * dp); | |
914 | extern afs_int32 VCreateVolumeDiskHeader(VolumeDiskHeader_t * hdr, | |
915 | struct DiskPartition64 * dp); | |
916 | extern 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 | */ | |
943 | typedef 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 | */ | |
961 | typedef void (*VWalkErrFunc)(struct DiskPartition64 *dp, const char *name, | |
962 | struct VolumeDiskHeader *hdr, void *rock); | |
963 | extern 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 | ||
1032 | hdr_static_inline(unsigned long) | |
1033 | afs_printable_VolumeId_lu(VolumeId d) { return (unsigned long) (d); } | |
1034 | ||
1035 | hdr_static_inline(unsigned int) | |
1036 | afs_printable_VnodeId_u(VnodeId d) { return (unsigned int) d; } | |
1037 | ||
1038 | #endif /* __volume_h */ |