threaded-volserver-progress-20031114
[openafs.git] / src / vol / volume.h
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
10 /*
11         System:         VICE-TWO
12         Module:         volume.h
13         Institution:    The Information Technology Center, Carnegie-Mellon University
14
15  */
16
17 #ifndef __volume_h
18 #define __volume_h  1
19
20 #include <afs/afssyscalls.h>
21 #include "voldefs.h"
22 #include "ihandle.h"
23 #define VolumeWriteable(vp)             (V_type(vp)==readwriteVolume)
24 #define VolumeWriteable2(vol)           (vol.type == readwriteVolume)
25 typedef bit32 FileOffset;       /* Offset in this file */
26 #define Date afs_uint32
27
28 #ifdef AFS_PTHREAD_ENV
29 #include <assert.h>
30 #include <pthread.h>
31 extern pthread_mutex_t vol_glock_mutex;
32 extern pthread_mutex_t vol_attach_mutex;
33 extern pthread_mutex_t vol_fsync_mutex;
34 extern pthread_cond_t vol_put_volume_cond;
35 extern pthread_cond_t vol_sleep_cond;
36 #define VATTACH_LOCK \
37     assert(pthread_mutex_lock(&vol_attach_mutex) == 0);
38 #define VATTACH_UNLOCK \
39     assert(pthread_mutex_unlock(&vol_attach_mutex) == 0);
40 #define VOL_LOCK \
41     assert(pthread_mutex_lock(&vol_glock_mutex) == 0);
42 #define VOL_UNLOCK \
43     assert(pthread_mutex_unlock(&vol_glock_mutex) == 0);
44 #define VFSYNC_LOCK \
45     assert(pthread_mutex_lock(&vol_fsync_mutex) == 0);
46 #define VFSYNC_UNLOCK \
47     assert(pthread_mutex_unlock(&vol_fsync_mutex) == 0);
48 #else /* AFS_PTHREAD_ENV */
49 #define VATTACH_LOCK
50 #define VATTACH_UNLOCK
51 #define VOL_LOCK
52 #define VOL_UNLOCK
53 #define VFSYNC_LOCK
54 #define VFSYNC_UNLOCK
55 #endif /* AFS_PTHREAD_ENV */
56
57 typedef enum { fileServer, volumeUtility, salvager } ProgramType;
58 extern ProgramType programType; /* The type of program using the package */
59
60 /* Some initialization parameters for the volume package */
61 /* Add new initialization parameters here */
62 extern int (*V_BreakVolumeCallbacks) ();
63 extern int (*vol_PollProc) ();
64 #define DOPOLL  ((vol_PollProc)? (*vol_PollProc)() : 0)
65
66 struct versionStamp {           /* Version stamp for critical volume files */
67     bit32 magic;                /* Magic number */
68     bit32 version;              /* Version number of this file, or software
69                                  * that created this file */
70 };
71
72 /* Magic numbers and version stamps for each type of file */
73 #define VOLUMEHEADERMAGIC       ((bit32)0x88a1bb3c)
74 #define VOLUMEINFOMAGIC         ((bit32)0x78a1b2c5)
75 #define SMALLINDEXMAGIC         0x99776655
76 #define LARGEINDEXMAGIC         0x88664433
77 #define MOUNTMAGIC              0x9a8b7c6d
78 #define ACLMAGIC                0x88877712
79 #define LINKTABLEMAGIC          0x99877712
80
81 #define VOLUMEHEADERVERSION     1
82 #define VOLUMEINFOVERSION       1
83 #define SMALLINDEXVERSION       1
84 #define LARGEINDEXVERSION       1
85 #define MOUNTVERSION            1
86 #define ACLVERSION              1
87 #define LINKTABLEVERSION        1
88
89 /*
90  * Define whether we are keeping detailed statistics on volume dealings.
91  */
92 #define OPENAFS_VOL_STATS       1
93
94 #if OPENAFS_VOL_STATS
95 /*
96  * Define various indices and counts used in keeping volume-level statistics.
97  */
98 #define VOL_STATS_NUM_RWINFO_FIELDS 4
99
100 #define VOL_STATS_SAME_NET      0       /*Within same site (total) */
101 #define VOL_STATS_SAME_NET_AUTH 1       /*Within same site (authenticated);
102                                          * (must be 1 more than above) */
103 #define VOL_STATS_DIFF_NET      2       /*From external site (total) */
104 #define VOL_STATS_DIFF_NET_AUTH 3       /*From external site (authenticated)
105                                          * (must be 1 more than above) */
106
107 #define VOL_STATS_NUM_TIME_RANGES 6
108
109 #define VOL_STATS_TIME_CAP_0        60  /*60 seconds */
110 #define VOL_STATS_TIME_CAP_1       600  /*10 minutes, in seconds */
111 #define VOL_STATS_TIME_CAP_2      3600  /*1 hour, in seconds */
112 #define VOL_STATS_TIME_CAP_3     86400  /*1 day, in seconds */
113 #define VOL_STATS_TIME_CAP_4    604800  /*1 week, in seconds */
114
115 #define VOL_STATS_NUM_TIME_FIELDS 6
116
117 #define VOL_STATS_TIME_IDX_0    0       /*0 secs to 60 secs */
118 #define VOL_STATS_TIME_IDX_1    1       /*1 min to 10 mins */
119 #define VOL_STATS_TIME_IDX_2    2       /*10 mins to 60 mins */
120 #define VOL_STATS_TIME_IDX_3    3       /*1 hr to 24 hrs */
121 #define VOL_STATS_TIME_IDX_4    4       /*1 day to 7 days */
122 #define VOL_STATS_TIME_IDX_5    5       /*Greater than 1 week */
123 #endif /* OPENAFS_VOL_STATS */
124
125 /* Volume header.  This is the contents of the named file representing
126  * the volume.  Read-only by the file server!
127  */
128 typedef struct VolumeHeader {
129     struct versionStamp stamp;  /* Must be first field */
130     VolumeId id;                /* Volume number */
131     VolumeId parent;            /* Read-write volume number (or this volume
132                                  * number if this is a read-write volume) */
133     Inode volumeInfo;
134     Inode smallVnodeIndex;
135     Inode largeVnodeIndex;
136     Inode volumeAcl;
137     Inode volumeMountTable;
138     Inode linkTable;
139 } VolumeHeader_t;
140
141
142 typedef struct VolumeDiskHeader {
143     struct versionStamp stamp;  /* Must be first field */
144     VolumeId id;                /* Volume number */
145     VolumeId parent;            /* Read-write volume number (or this volume
146                                  * number if this is a read-write volume) */
147     afs_int32 volumeInfo_lo;
148     afs_int32 smallVnodeIndex_lo;
149     afs_int32 largeVnodeIndex_lo;
150     afs_int32 volumeAcl_lo;
151     afs_int32 volumeMountTable_lo;
152     afs_int32 volumeInfo_hi;
153     afs_int32 smallVnodeIndex_hi;
154     afs_int32 largeVnodeIndex_hi;
155     afs_int32 volumeAcl_hi;
156     afs_int32 volumeMountTable_hi;
157     afs_int32 linkTable_lo;
158     afs_int32 linkTable_hi;
159     /* If you add fields, add them before here and reduce the size of  array */
160     bit32 reserved[3];
161 } VolumeDiskHeader_t;
162
163 /* A vnode index file header */
164 struct IndexFileHeader {
165     struct versionStamp stamp;
166 };
167
168
169 /******************************************************************************/
170 /* Volume Data which is stored on disk and can also be maintained in memory.  */
171 /******************************************************************************/
172 typedef struct VolumeDiskData {
173     struct versionStamp stamp;  /* Must be first field */
174     VolumeId id;                /* Volume id--unique over all systems */
175 #define VNAMESIZE 32            /* including 0 byte */
176     char name[VNAMESIZE];       /* Unofficial name for the volume */
177     byte inUse;                 /* Volume is being used (perhaps it is online),
178                                  * or the system crashed while it was used */
179     byte inService;             /* Volume in service, not necessarily on line
180                                  * This bit is set by an operator/system
181                                  * programmer.  Manually taking a volume offline
182                                  * always clears the inService bit. Taking
183                                  * it out of service also takes it offline */
184     byte blessed;               /* Volume is administratively blessed with
185                                  * the ability to go on line.  Set by a system
186                                  * administrator. Clearing this bit will
187                                  * take the volume offline */
188     byte needsSalvaged;         /* Volume needs salvaged--an unrecoverable
189                                  * error occured to the volume.  Note:  a volume
190                                  * may still require salvage even if this
191                                  * flag isn't set--e.g. if a system crash
192                                  * occurred while the volume was on line. */
193     bit32 uniquifier;           /* Next vnode uniquifier for this volume */
194     int type;                   /* */
195     VolId parentId;             /* Id of parent, if type==readonly */
196     VolId cloneId;              /* Latest read-only clone, if type==readwrite,
197                                  * 0 if the volume has never been cloned.  Note: the
198                                  * indicated volume does not necessarily exist (it
199                                  * may have been deleted since cloning). */
200     VolId backupId;             /* Latest backup copy of this read write volume */
201     VolId restoredFromId;       /* The id in the dump this volume was restored from--used simply
202                                  * to make sure that an incremental dump is not restored on top
203                                  * of something inappropriate:  Note:  this field itself is NEVER
204                                  * dumped!!! */
205     byte needsCallback;         /* Set by the salvager if anything was changed
206                                  * about the volume.  Note:  this is not set by
207                                  * clone/makebackups when setting the copy-on-write
208                                  * flag in directories; this flag is not seen by
209                                  * the clients. */
210 #define DESTROY_ME      0xD3
211     byte destroyMe;             /* If this is set to DESTROY_ME, then the salvager should destroy
212                                  * this volume; it is bogus (left over from an aborted  volume move,
213                                  * for example).  Note:  if this flag is on, then inService should
214                                  * be OFF--only the salvager checks this flag */
215 #ifdef ALPHA_DUX40_ENV
216 #define DONT_SALVAGE    0xE6
217 #else                           /* ALPHA_DUX40_ENV */
218 #define DONT_SALVAGE    0xE5
219 #endif                          /* ALPHA_DUX40_ENV */
220     byte dontSalvage;           /* If this is on, then don't bother salvaging this volume */
221     byte reserveb3;
222
223     bit32 reserved1[6];
224
225
226     /* Administrative stuff */
227     int maxquota;               /* Quota maximum, 1K blocks */
228     int minquota;               /* Quota minimum, 1K blocks */
229     int maxfiles;               /* Maximum number of files (i.e. inodes) */
230     bit32 accountNumber;        /* Uninterpreted account number */
231     bit32 owner;                /* The person administratively responsible
232                                  * for this volume */
233     int reserved2[8];           /* Other administrative constraints */
234
235     /* Resource usage & statistics */
236     int filecount;              /* Actual number of files */
237     int diskused;               /* Actual disk space used, 1K blocks */
238     int dayUse;                 /* Metric for today's usage of this volume so far */
239     int weekUse[7];             /* Usage of the volume for the last week.
240                                  * weekUse[0] is for most recent complete 24 hour period
241                                  * of measurement; week[6] is 7 days ago */
242     Date dayUseDate;            /* Date the dayUse statistics refer to; the week use stats
243                                  * are the preceding 7 days */
244     int reserved3[11];          /* Other stats here */
245
246     /* Server supplied dates */
247     Date creationDate;          /* Creation date for a read/write
248                                  * volume; cloning date for original copy of
249                                  * a readonly volume (replicated volumes have
250                                  * the same creation date) */
251     Date accessDate;            /* Last access time by a user, large granularity */
252     Date updateDate;            /* Last modification by user */
253     Date expirationDate;        /* 0 if it never expires */
254     Date backupDate;            /* last time a backup clone was taken */
255
256     /* Time that this copy of this volume was made.  NEVER backed up.  This field is only
257      * set when the copy is created */
258     Date copyDate;
259
260 #if OPENAFS_VOL_STATS
261     bit32 stat_initialized;     /*Are the stat fields below set up? */
262     bit32 reserved4[7];
263 #else
264     bit32 reserved4[8];
265 #endif                          /* OPENAFS_VOL_STATS */
266
267     /* messages */
268 #define VMSGSIZE 128
269     char offlineMessage[VMSGSIZE];      /* Why the volume is offline */
270 #if OPENAFS_VOL_STATS
271 #define VOL_STATS_BYTES 128
272     /*
273      * Keep per-volume aggregate statistics on type and distance of access,
274      * along with authorship info.
275      */
276     bit32 stat_reads[VOL_STATS_NUM_RWINFO_FIELDS];
277     bit32 stat_writes[VOL_STATS_NUM_RWINFO_FIELDS];
278     bit32 stat_fileSameAuthor[VOL_STATS_NUM_TIME_FIELDS];
279     bit32 stat_fileDiffAuthor[VOL_STATS_NUM_TIME_FIELDS];
280     bit32 stat_dirSameAuthor[VOL_STATS_NUM_TIME_FIELDS];
281     bit32 stat_dirDiffAuthor[VOL_STATS_NUM_TIME_FIELDS];
282 #else
283     char motd[VMSGSIZE];        /* Volume "message of the day" */
284 #endif                          /* OPENAFS_VOL_STATS */
285
286 } VolumeDiskData;
287
288
289 /**************************************/
290 /* Memory resident volume information */
291 /**************************************/
292 typedef struct Volume {
293     struct Volume *hashNext;    /* Next in hash resolution table */
294     VolumeId hashid;            /* Volume number -- for hash table lookup */
295     struct volHeader *header;   /* Cached disk data */
296     Device device;              /* Unix device for the volume */
297     struct DiskPartition
298      *partition;                /* Information about the Unix partition */
299     struct vnodeIndex {
300         IHandle_t *handle;      /* Unix inode holding this index */
301         byte *bitmap;           /* Index bitmap */
302         afs_uint32 bitmapSize;  /* length of bitmap, in bytes */
303         afs_uint32 bitmapOffset;        /* Which byte address of the first long to
304                                          * start search from in bitmap */
305     } vnodeIndex[nVNODECLASSES];
306     IHandle_t *linkHandle;
307     Unique nextVnodeUnique;     /* Derived originally from volume uniquifier.
308                                  * This is the actual next version number to
309                                  * assign; the uniquifier is bumped by 200 and
310                                  * and written to disk every 200 file creates
311                                  * If the volume is shutdown gracefully, the
312                                  * uniquifier should be rewritten with the
313                                  * value nextVnodeVersion */
314     IHandle_t *diskDataHandle;  /* Unix inode holding general volume info */
315     bit16 vnodeHashOffset;      /* Computed by HashOffset function in vnode.h.
316                                  * Assigned to the volume when initialized. 
317                                  * Added to vnode number for hash table index */
318     byte shuttingDown;          /* This volume is going to be detached */
319     byte goingOffline;          /* This volume is going offline */
320     bit32 cacheCheck;           /* Online sequence number to be used to invalidate vnode cache entries
321                                  * that stayed around while a volume was offline */
322     short nUsers;               /* Number of users of this volume header */
323     byte needsPutBack;          /* For a volume utility, this flag is set if we need
324                                  * to give the volume back when we detach it.  The server has
325                                  * certain modes where it doesn't detach the volume, and
326                                  * if we give it back spuriously, the server aborts.  This field
327                                  * is meaningless on the file server */
328     byte specialStatus;         /* An error code to return on VGetVolume: the
329                                  * volume is unavailable for the reason quoted,
330                                  * currently VBUSY or VMOVED */
331     afs_uint32 updateTime;      /* Time that this volume was put on the updated
332                                  * volume list--the list of volumes that will be
333                                  * salvaged should the file server crash */
334 } Volume;
335
336 struct volHeader {
337     struct volHeader *prev, *next;      /* LRU pointers */
338     VolumeDiskData diskstuff;   /* General volume info read from disk */
339     Volume *back;               /* back pointer to current volume structure */
340 };
341
342 /* These macros are used to export fields within the volume header.  This was added
343    to facilitate changing the actual representation */
344
345 #define V_device(vp)            ((vp)->device)
346 #define V_partition(vp)         ((vp)->partition)
347 #define V_diskDataHandle(vp)    ((vp)->diskDataHandle)
348 #define V_vnodeIndex(vp)        ((vp)->vnodeIndex)
349 #define V_nextVnodeUnique(vp)   ((vp)->nextVnodeUnique)
350 #define V_linkHandle(vp)        ((vp)->linkHandle)
351
352 /* N.B. V_id must be this, rather than vp->id, or some programs will break, probably */
353 #define V_stamp(vp)             ((vp)->header->diskstuff.stamp)
354 #define V_id(vp)                ((vp)->header->diskstuff.id)
355 #define V_name(vp)              ((vp)->header->diskstuff.name)
356 #define V_inUse(vp)             ((vp)->header->diskstuff.inUse)
357 #define V_inService(vp)         ((vp)->header->diskstuff.inService)
358 #define V_blessed(vp)           ((vp)->header->diskstuff.blessed)
359 #define V_needsSalvaged(vp)     ((vp)->header->diskstuff.needsSalvaged)
360 #define V_uniquifier(vp)        ((vp)->header->diskstuff.uniquifier)
361 #define V_type(vp)              ((vp)->header->diskstuff.type)
362 #define V_parentId(vp)          ((vp)->header->diskstuff.parentId)
363 #define V_cloneId(vp)           ((vp)->header->diskstuff.cloneId)
364 #define V_backupId(vp)          ((vp)->header->diskstuff.backupId)
365 #define V_restoredFromId(vp)    ((vp)->header->diskstuff.restoredFromId)
366 #define V_needsCallback(vp)     ((vp)->header->diskstuff.needsCallback)
367 #define V_destroyMe(vp)         ((vp)->header->diskstuff.destroyMe)
368 #define V_dontSalvage(vp)       ((vp)->header->diskstuff.dontSalvage)
369 #define V_maxquota(vp)          ((vp)->header->diskstuff.maxquota)
370 #define V_minquota(vp)          ((vp)->header->diskstuff.minquota)
371 #define V_maxfiles(vp)          ((vp)->header->diskstuff.maxfiles)
372 #define V_accountNumber(vp)     ((vp)->header->diskstuff.accountNumber)
373 #define V_owner(vp)             ((vp)->header->diskstuff.owner)
374 #define V_filecount(vp)         ((vp)->header->diskstuff.filecount)
375 #define V_diskused(vp)          ((vp)->header->diskstuff.diskused)
376 #define V_dayUse(vp)            ((vp)->header->diskstuff.dayUse)
377 #define V_weekUse(vp)           ((vp)->header->diskstuff.weekUse)
378 #define V_dayUseDate(vp)        ((vp)->header->diskstuff.dayUseDate)
379 #define V_creationDate(vp)      ((vp)->header->diskstuff.creationDate)
380 #define V_accessDate(vp)        ((vp)->header->diskstuff.accessDate)
381 #define V_updateDate(vp)        ((vp)->header->diskstuff.updateDate)
382 #define V_expirationDate(vp)    ((vp)->header->diskstuff.expirationDate)
383 #define V_backupDate(vp)        ((vp)->header->diskstuff.backupDate)
384 #define V_copyDate(vp)          ((vp)->header->diskstuff.copyDate)
385 #define V_offlineMessage(vp)    ((vp)->header->diskstuff.offlineMessage)
386 #define V_disk(vp)              ((vp)->header->diskstuff)
387 #define V_motd(vp)              ((vp)->header->diskstuff.motd)
388 #if OPENAFS_VOL_STATS
389 #define V_stat_initialized(vp)  ((vp)->header->diskstuff.stat_initialized)
390 #define V_stat_area(vp)         (((vp)->header->diskstuff.stat_reads))
391 #define V_stat_reads(vp, idx)   (((vp)->header->diskstuff.stat_reads)[idx])
392 #define V_stat_writes(vp, idx)  (((vp)->header->diskstuff.stat_writes)[idx])
393 #define V_stat_fileSameAuthor(vp, idx) (((vp)->header->diskstuff.stat_fileSameAuthor)[idx])
394 #define V_stat_fileDiffAuthor(vp, idx) (((vp)->header->diskstuff.stat_fileDiffAuthor)[idx])
395 #define V_stat_dirSameAuthor(vp, idx)  (((vp)->header->diskstuff.stat_dirSameAuthor)[idx])
396 #define V_stat_dirDiffAuthor(vp, idx)  (((vp)->header->diskstuff.stat_dirDiffAuthor)[idx])
397 #endif /* OPENAFS_VOL_STATS */
398
399 /* File offset computations.  The offset values in the volume header are
400    computed with these macros -- when the file is written only!! */
401 #define VOLUME_MOUNT_TABLE_OFFSET(Volume)       (sizeof (VolumeDiskData))
402 #define VOLUME_BITMAP_OFFSET(Volume)    \
403         (sizeof (VolumeDiskData) + (Volume)->disk.mountTableSize)
404
405
406 extern char *VSalvageMessage;   /* Canonical message when a volume is forced
407                                  * offline */
408 extern Volume *VGetVolume(Error * ec, VolId volumeId);
409 extern Volume *VGetVolume_r(Error * ec, VolId volumeId);
410 extern void VPutVolume(Volume *);
411 extern void VPutVolume_r(Volume *);
412 extern void VOffline(Volume * vp, char *message);
413 extern void VOffline_r(Volume * vp, char *message);
414 extern int VConnectFS(void);
415 extern int VConnectFS_r(void);
416 extern Volume *VAttachVolume(Error * ec, VolumeId volumeId, int mode);
417 extern Volume *VAttachVolume_r(Error * ec, VolumeId volumeId, int mode);
418 extern Volume *VCreateVolume(Error * ec, char *partname, VolId volumeId,
419                              VolId parentId);
420 extern Volume *VCreateVolume_r(Error * ec, char *partname, VolId volumeId,
421                                VolId parentId);
422 extern VnodeId VAllocBitmapEntry(Error * ec, Volume * vp,
423                                  struct vnodeIndex *index);
424 extern VnodeId VAllocBitmapEntry_r(Error * ec, Volume * vp,
425                                    struct vnodeIndex *index);
426 extern void VFreeBitMapEntry(Error * ec, register struct vnodeIndex *index,
427                              unsigned bitNumber);
428 extern void VFreeBitMapEntry_r(Error * ec, register struct vnodeIndex *index,
429                                unsigned bitNumber);
430 extern int VolumeNumber(char *name);
431 extern char *VolumeExternalName(VolumeId volumeId);
432 extern Volume *VAttachVolumeByName(Error * ec, char *partition, char *name,
433                                    int mode);
434 extern Volume *VAttachVolumeByName_r(Error * ec, char *partition, char *name,
435                                      int mode);
436 extern void VShutdown(void);
437 extern void VUpdateVolume(Error * ec, Volume * vp);
438 extern void VUpdateVolume_r(Error * ec, Volume * vp);
439 extern void VAddToVolumeUpdateList(Error * ec, Volume * vp);
440 extern void VAddToVolumeUpdateList_r(Error * ec, Volume * vp);
441 extern void VDetachVolume(Error * ec, Volume * vp);
442 extern void VDetachVolume_r(Error * ec, Volume * vp);
443 extern void VForceOffline(Volume * vp);
444 extern void VForceOffline_r(Volume * vp);
445 extern void VBumpVolumeUsage(register Volume * vp);
446 extern void VBumpVolumeUsage_r(register Volume * vp);
447 extern void VSetDiskUsage(void);
448 extern void VPrintCacheStats(void);
449 extern void VReleaseVnodeFiles_r(Volume * vp);
450 extern void VCloseVnodeFiles_r(Volume * vp);
451 extern struct DiskPartition *VGetPartition(char *name, int abortp);
452 extern struct DiskPartition *VGetPartition_r(char *name, int abortp);
453 extern int VInitVolumePackage(ProgramType pt, int nLargeVnodes,
454                               int nSmallVnodes, int connect, int volcache);
455 extern void DiskToVolumeHeader(VolumeHeader_t * h, VolumeDiskHeader_t * dh);
456 extern void VolumeHeaderToDisk(VolumeDiskHeader_t * dh, VolumeHeader_t * h);
457 extern void VTakeOffline_r(register Volume * vp);
458 extern void VTakeOffline(register Volume * vp);
459
460
461 /* Naive formula relating number of file size to number of 1K blocks in file */
462 /* Note:  we charge 1 block for 0 length files so the user can't store
463    an inifite number of them; for most files, we give him the inode, vnode,
464    and indirect block overhead, for FREE! */
465 #define nBlocks(bytes) ((afs_sfsize_t)((bytes) == 0? 1: (((afs_sfsize_t)(bytes))+1023)/1024))
466
467 /* Client process id -- file server sends a Check volumes signal back to the client at this pid */
468 #define CLIENTPID       "/vice/vol/clientpid"
469
470 /* Modes of attachment, for VAttachVolume[ByName] to convey to the file server */
471 #define V_READONLY 1            /* Absolutely no updates will be done to the volume */
472 #define V_CLONE    2            /* Cloning the volume:  if it is read/write, then directory
473                                  * version numbers will change.  Header will be updated.  If
474                                  * the volume is read-only, the file server may continue to
475                                  * server it; it may also continue to server it in read/write
476                                  * mode if the writes are deferred */
477 #define V_VOLUPD   3            /* General update or volume purge is possible.  Volume must
478                                  * go offline */
479 #define V_DUMP     4            /* A dump of the volume is requested; the volume can be served
480                                  * read-only during this time */
481 #define V_SECRETLY 5            /* Secret attach of the volume.  This is used to attach a volume
482                                  * which the file server doesn't know about--and which it shouldn't
483                                  * know about yet, since the volume has just been created and
484                                  * is somewhat bogus.  Required to make sure that a file server
485                                  * never knows about more than one copy of the same volume--when
486                                  * a volume is moved from one partition to another on a single
487                                  * server */
488
489 #if     defined(NEARINODE_HINT)
490 #define V_pref(vp,nearInode)  nearInodeHash(V_id(vp),(nearInode)); (nearInode) %= V_partition(vp)->f_files
491 #else
492 #define V_pref(vp,nearInode)   nearInode = 0
493 #endif /* NEARINODE_HINT */
494
495 #endif /* __volume_h */