Remove DUX/OSF code
[openafs.git] / src / vol / volume.h
index d34470b..f1739de 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 2000, International Business Machines Corporation and others.
  * All Rights Reserved.
- * 
+ *
  * This software has been released under the terms of the IBM Public
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
@@ -36,9 +36,9 @@ typedef bit32 FileOffset;     /* Offset in this file */
 
 #ifdef VOL_LOCK_DEBUG
 #define VOL_LOCK_ASSERT_HELD \
-    assert(vol_glock_holder == pthread_self())
+    opr_Assert(vol_glock_holder == pthread_self())
 #define VOL_LOCK_ASSERT_UNHELD \
-    assert(vol_glock_holder == 0)
+    opr_Assert(vol_glock_holder == 0)
 #define _VOL_LOCK_SET_HELD \
     vol_glock_holder = pthread_self()
 #define _VOL_LOCK_SET_UNHELD \
@@ -62,49 +62,44 @@ typedef bit32 FileOffset;   /* Offset in this file */
 
 
 #ifdef AFS_PTHREAD_ENV
-#include <assert.h>
 #include <pthread.h>
 extern pthread_mutex_t vol_glock_mutex;
 extern pthread_mutex_t vol_trans_mutex;
 extern pthread_cond_t vol_put_volume_cond;
 extern pthread_cond_t vol_sleep_cond;
+extern pthread_cond_t vol_vinit_cond;
 extern ih_init_params vol_io_params;
 extern int vol_attach_threads;
 #ifdef VOL_LOCK_DEBUG
 extern pthread_t vol_glock_holder;
 #define VOL_LOCK \
     do { \
-        assert(pthread_mutex_lock(&vol_glock_mutex) == 0); \
-        assert(vol_glock_holder == 0); \
-        vol_glock_holder = pthread_self(); \
+       opr_mutex_enter(&vol_glock_mutex); \
+       VOL_LOCK_ASSERT_UNHELD; \
+       _VOL_LOCK_SET_HELD; \
     } while (0)
 #define VOL_UNLOCK \
     do { \
         VOL_LOCK_ASSERT_HELD; \
-        vol_glock_holder = 0; \
-        assert(pthread_mutex_unlock(&vol_glock_mutex) == 0); \
+       _VOL_LOCK_SET_UNHELD; \
+       opr_mutex_exit(&vol_glock_mutex); \
     } while (0)
 #define VOL_CV_WAIT(cv) \
     do { \
         VOL_LOCK_DBG_CV_WAIT_BEGIN; \
-        assert(pthread_cond_wait((cv), &vol_glock_mutex) == 0); \
+       opr_cv_wait((cv), &vol_glock_mutex); \
         VOL_LOCK_DBG_CV_WAIT_END; \
     } while (0)
 #else /* !VOL_LOCK_DEBUG */
-#define VOL_LOCK \
-    assert(pthread_mutex_lock(&vol_glock_mutex) == 0)
-#define VOL_UNLOCK \
-    assert(pthread_mutex_unlock(&vol_glock_mutex) == 0)
-#define VOL_CV_WAIT(cv) assert(pthread_cond_wait((cv), &vol_glock_mutex) == 0)
+#define VOL_LOCK opr_mutex_enter(&vol_glock_mutex)
+#define VOL_UNLOCK opr_mutex_exit(&vol_glock_mutex)
+#define VOL_CV_WAIT(cv) opr_cv_wait((cv), &vol_glock_mutex)
 #endif /* !VOL_LOCK_DEBUG */
-#define VSALVSYNC_LOCK \
-    assert(pthread_mutex_lock(&vol_salvsync_mutex) == 0)
-#define VSALVSYNC_UNLOCK \
-    assert(pthread_mutex_unlock(&vol_salvsync_mutex) == 0)
-#define VTRANS_LOCK \
-    assert(pthread_mutex_lock(&vol_trans_mutex) == 0)
-#define VTRANS_UNLOCK \
-    assert(pthread_mutex_unlock(&vol_trans_mutex) == 0)
+
+#define VSALVSYNC_LOCK opr_mutex_enter(&vol_salvsync_mutex)
+#define VSALVSYNC_UNLOCK opr_mutex_exit(&vol_salvsync_mutex)
+#define VTRANS_LOCK opr_mutex_enter(&vol_trans_mutex)
+#define VTRANS_UNLOCK opr_mutex_exit(&vol_trans_mutex)
 #else /* AFS_PTHREAD_ENV */
 #define VOL_LOCK
 #define VOL_UNLOCK
@@ -124,7 +119,7 @@ typedef enum {
     salvageServer       = 4,    /**< dafs online salvager */
     debugUtility        = 5,    /**< fssync-debug or similar utility */
     volumeServer        = 6,    /**< the volserver process */
-    volumeSalvager      = 7,    /**< the standalone single-volume salvager */
+    volumeSalvager      = 7     /**< the standalone single-volume salvager */
 } ProgramType;
 extern ProgramType programType;        /* The type of program using the package */
 
@@ -177,9 +172,15 @@ typedef enum {
     VOL_STATE_VNODE_CLOSE       = 17,   /**< volume is busy closing vnodes */
     VOL_STATE_VNODE_RELEASE     = 18,   /**< volume is busy releasing vnodes */
     VOL_STATE_VLRU_ADD          = 19,   /**< volume is busy being added to a VLRU queue */
+    VOL_STATE_DELETED           = 20,   /**< volume has been deleted by the volserver */
+    VOL_STATE_SALVAGE_REQ       = 21,   /**< volume has been requested to be salvaged,
+                                         *   but is waiting for other users to go away
+                                         *   so it can be offlined */
+    VOL_STATE_SCANNING_RXCALLS  = 22,   /**< volume is scanning vp->rx_call_list
+                                         *   to interrupt RX calls */
     /* please add new states directly above this line */
-    VOL_STATE_FREED             = 20,   /**< debugging aid */
-    VOL_STATE_COUNT             = 21,   /**< total number of valid states */
+    VOL_STATE_FREED             = 23,   /**< debugging aid */
+    VOL_STATE_COUNT             = 24    /**< total number of valid states */
 } VolState;
 
 /**
@@ -194,6 +195,7 @@ enum VolFlags {
     VOL_IS_BUSY           = 0x20,    /**< volume is not to be free()d */
     VOL_ON_VLRU           = 0x40,    /**< volume is on the VLRU */
     VOL_HDR_DONTSALV      = 0x80,    /**< volume header DONTSALVAGE flag is set */
+    VOL_LOCKED            = 0x100    /**< volume is disk-locked (@see VLockVolumeNB) */
 };
 
 /* VPrintExtendedCacheStats flags */
@@ -217,7 +219,7 @@ typedef enum {
     VLRU_QUEUE_CANDIDATE  = 3,  /**< soft detach candidate pool */
     VLRU_QUEUE_HELD       = 4,  /*   volumes which are not allowed
                                 *   to be soft detached */
-    VLRU_QUEUE_INVALID    = 5,  /**< invalid queue id */
+    VLRU_QUEUE_INVALID    = 5   /**< invalid queue id */
 } VLRUQueueName;
 
 /* default scanner timing parameters */
@@ -248,6 +250,30 @@ typedef struct VolumePackageOptions {
                                    * find a bad vol) */
     afs_int32 canUseFSSYNC;       /**< can we use the FSSYNC channel? */
     afs_int32 canUseSALVSYNC;     /**< can we use the SALVSYNC channel? (DAFS) */
+    afs_int32 unsafe_attach;      /**< can we bypass checking the inUse vol
+                                   *   header on attach? */
+    void (*interrupt_rxcall) (struct rx_call *call, afs_int32 error);
+                                  /**< callback to interrupt RX calls accessing
+                                   *   a going-offline volume */
+    afs_int32 offline_timeout;    /**< how long (in seconds) to wait before
+                                   *   interrupting RX calls accessing a
+                                   *   going-offline volume. -1 disables,
+                                   *   0 means immediately. */
+    afs_int32 offline_shutdown_timeout;
+                                  /**< how long (in seconds) to wait before
+                                   *   interrupting RX calls accessing a
+                                   *   going-offline volume during shutdown.
+                                   *   -1 disables, 0 means immediately.
+                                   *   Note that the timeout time is calculated
+                                   *   once, when we encounter the first going-
+                                   *   offline volume during shutdown. So if we
+                                   *   encounter multiple going-offline volumes
+                                   *   during shutdown, we will still only wait
+                                   *   for this amount of time in total, not e.g.
+                                   *   for each going-offline volume encountered. */
+    afs_int32 usage_threshold;    /*< number of accesses before writing volume header */
+    afs_int32 usage_rate_limit;   /*< minimum number of seconds before writing volume
+                                   *  header, after usage_threshold is exceeded */
 } VolumePackageOptions;
 
 /* Magic numbers and version stamps for each type of file */
@@ -267,12 +293,7 @@ typedef struct VolumePackageOptions {
 #define ACLVERSION             1
 #define LINKTABLEVERSION       1
 
-/*
- * Define whether we are keeping detailed statistics on volume dealings.
- */
-#define OPENAFS_VOL_STATS      1
 
-#if OPENAFS_VOL_STATS
 /*
  * Define various indices and counts used in keeping volume-level statistics.
  */
@@ -301,7 +322,6 @@ typedef struct VolumePackageOptions {
 #define VOL_STATS_TIME_IDX_3   3       /*1 hr to 24 hrs */
 #define VOL_STATS_TIME_IDX_4   4       /*1 day to 7 days */
 #define VOL_STATS_TIME_IDX_5   5       /*Greater than 1 week */
-#endif /* OPENAFS_VOL_STATS */
 
 /* Volume header.  This is the contents of the named file representing
  * the volume.  Read-only by the file server!
@@ -373,13 +393,13 @@ typedef struct VolumeDiskData {
                                 * occurred while the volume was on line. */
     bit32 uniquifier;          /* Next vnode uniquifier for this volume */
     int type;                  /* */
-    VolId parentId;            /* Id of parent, if type==readonly */
-    VolId cloneId;             /* Latest read-only clone, if type==readwrite,
+    VolumeId parentId;         /* Id of parent, if type==readonly */
+    VolumeId cloneId;          /* Latest read-only clone, if type==readwrite,
                                 * 0 if the volume has never been cloned.  Note: the
                                 * indicated volume does not necessarily exist (it
                                 * may have been deleted since cloning). */
-    VolId backupId;            /* Latest backup copy of this read write volume */
-    VolId restoredFromId;      /* The id in the dump this volume was restored from--used simply
+    VolumeId backupId; /* Latest backup copy of this read write volume */
+    VolumeId restoredFromId;   /* The id in the dump this volume was restored from--used simply
                                 * to make sure that an incremental dump is not restored on top
                                 * of something inappropriate:  Note:  this field itself is NEVER
                                 * dumped!!! */
@@ -393,11 +413,7 @@ typedef struct VolumeDiskData {
                                 * this volume; it is bogus (left over from an aborted  volume move,
                                 * for example).  Note:  if this flag is on, then inService should
                                 * be OFF--only the salvager checks this flag */
-#ifdef ALPHA_DUX40_ENV
-#define DONT_SALVAGE   0xE6
-#else                          /* ALPHA_DUX40_ENV */
 #define DONT_SALVAGE   0xE5
-#endif                         /* ALPHA_DUX40_ENV */
     byte dontSalvage;          /* If this is on, then don't bother salvaging this volume */
     byte reserveb3;
 
@@ -431,7 +447,7 @@ typedef struct VolumeDiskData {
                                 * a readonly volume (replicated volumes have
                                 * the same creation date) */
     Date accessDate;           /* Last access time by a user, large granularity */
-    Date updateDate;           /* Last modification by user */
+    Date updateDate;           /* Last modification by user or salvager */
     Date expirationDate;       /* 0 if it never expires */
     Date backupDate;           /* last time a backup clone was taken */
 
@@ -439,17 +455,12 @@ typedef struct VolumeDiskData {
      * set when the copy is created */
     Date copyDate;
 
-#if OPENAFS_VOL_STATS
     bit32 stat_initialized;    /*Are the stat fields below set up? */
     bit32 reserved4[7];
-#else
-    bit32 reserved4[8];
-#endif                         /* OPENAFS_VOL_STATS */
 
     /* messages */
 #define VMSGSIZE 128
     char offlineMessage[VMSGSIZE];     /* Why the volume is offline */
-#if OPENAFS_VOL_STATS
 #define VOL_STATS_BYTES 128
     /*
      * Keep per-volume aggregate statistics on type and distance of access,
@@ -461,9 +472,6 @@ typedef struct VolumeDiskData {
     bit32 stat_fileDiffAuthor[VOL_STATS_NUM_TIME_FIELDS];
     bit32 stat_dirSameAuthor[VOL_STATS_NUM_TIME_FIELDS];
     bit32 stat_dirDiffAuthor[VOL_STATS_NUM_TIME_FIELDS];
-#else
-    char motd[VMSGSIZE];       /* Volume "message of the day" */
-#endif                         /* OPENAFS_VOL_STATS */
 
 } VolumeDiskData;
 
@@ -472,7 +480,7 @@ typedef struct VolumeDiskData {
 /* Memory resident volume information */
 /**************************************/
 
-/** 
+/**
  * global volume package stats.
  */
 typedef struct VolPkgStats {
@@ -606,7 +614,11 @@ typedef struct VolumeOnlineSalvage {
     int reason;                 /**< reason for requesting online salvage */
     byte requested;             /**< flag specifying that salvage should be scheduled */
     byte scheduled;             /**< flag specifying whether online salvage scheduled */
-    byte reserved[2];           /**< padding */
+    byte scheduling;            /**< if nonzero, this volume has entered
+                                 *   VCheckSalvage(), so if we recurse into
+                                 *   VCheckSalvage() with this set, exit immediately
+                                 *   to avoid recursing forever */
+    byte reserved[1];           /**< padding */
 } VolumeOnlineSalvage;
 
 /**
@@ -618,6 +630,14 @@ typedef struct VolumeVLRUState {
 } VolumeVLRUState;
 #endif /* AFS_DEMAND_ATTACH_FS */
 
+/**
+ * node for a volume's rx_call_list.
+ */
+struct VCallByVol {
+    struct rx_queue q;
+    struct rx_call *call;
+};
+
 typedef struct Volume {
     struct rx_queue q;          /* Volume hash chain pointers */
     VolumeId hashid;           /* Volume number -- for hash table lookup */
@@ -641,18 +661,20 @@ typedef struct Volume {
                                 * uniquifier should be rewritten with the
                                 * value nextVnodeVersion */
     IHandle_t *diskDataHandle; /* Unix inode holding general volume info */
-    bit16 vnodeHashOffset;     /* Computed by HashOffset function in vnode.h.
-                                * Assigned to the volume when initialized. 
-                                * Added to vnode number for hash table index */
     byte shuttingDown;         /* This volume is going to be detached */
     byte goingOffline;         /* This volume is going offline */
     bit32 cacheCheck;          /* Online sequence number to be used to invalidate vnode cache entries
                                 * that stayed around while a volume was offline */
     short nUsers;              /* Number of users of this volume header */
-    byte needsPutBack;         /* For a volume utility, this flag is set if we need
-                                * to give the volume back when we detach it.  The server has
+#define VOL_PUTBACK 1
+#define VOL_PUTBACK_DELETE 2
+    byte needsPutBack;         /* For a volume utility, this flag is set to VOL_PUTBACK if we
+                                * need to give the volume back when we detach it.  The server has
                                 * certain modes where it doesn't detach the volume, and
-                                * if we give it back spuriously, the server aborts.  This field
+                                * if we give it back spuriously, the server aborts. If set to
+                                * VOL_PUTBACK_DELETE, it indicates that we need to tell the
+                                * fileserver that the volume is gone entirely, instead of just
+                                * giving the volume back to the fileserver. This field
                                 * is meaningless on the file server */
     byte specialStatus;                /* An error code to return on VGetVolume: the
                                 * volume is unavailable for the reason quoted,
@@ -662,6 +684,8 @@ typedef struct Volume {
                                 * volume list--the list of volumes that will be
                                 * salvaged should the file server crash */
     struct rx_queue vnode_list; /**< linked list of cached vnodes for this volume */
+    struct rx_queue rx_call_list; /**< linked list of split RX calls using this
+                                   *   volume (fileserver only) */
 #ifdef AFS_DEMAND_ATTACH_FS
     VolState attach_state;      /* what stage of attachment has been completed */
     afs_uint32 attach_flags;    /* flags related to attachment state */
@@ -675,6 +699,8 @@ typedef struct Volume {
     VolumeVLRUState vlru;         /* state specific to the VLRU */
     FSSYNC_VolOp_info * pending_vol_op;  /* fssync command info for any pending vol ops */
 #endif /* AFS_DEMAND_ATTACH_FS */
+    int usage_bumps_outstanding; /**< to rate limit the usage update i/o by accesses */
+    int usage_bumps_next_write;  /**< to rate limit the usage update i/o by time */
 } Volume;
 
 struct volHeader {
@@ -735,7 +761,6 @@ struct volHeader {
 #define V_offlineMessage(vp)   ((vp)->header->diskstuff.offlineMessage)
 #define V_disk(vp)             ((vp)->header->diskstuff)
 #define V_motd(vp)             ((vp)->header->diskstuff.motd)
-#if OPENAFS_VOL_STATS
 #define V_stat_initialized(vp) ((vp)->header->diskstuff.stat_initialized)
 #define V_stat_area(vp)                (((vp)->header->diskstuff.stat_reads))
 #define V_stat_reads(vp, idx)  (((vp)->header->diskstuff.stat_reads)[idx])
@@ -744,8 +769,7 @@ struct volHeader {
 #define V_stat_fileDiffAuthor(vp, idx) (((vp)->header->diskstuff.stat_fileDiffAuthor)[idx])
 #define V_stat_dirSameAuthor(vp, idx)  (((vp)->header->diskstuff.stat_dirSameAuthor)[idx])
 #define V_stat_dirDiffAuthor(vp, idx)  (((vp)->header->diskstuff.stat_dirDiffAuthor)[idx])
-#endif /* OPENAFS_VOL_STATS */
-#define V_volUpCounter(vp)             ((vp)->header->diskstuff.volUpdateCounter)
+#define V_volUpdateCounter(vp)         ((vp)->header->diskstuff.volUpdateCounter)
 
 /* File offset computations.  The offset values in the volume header are
    computed with these macros -- when the file is written only!! */
@@ -756,9 +780,12 @@ struct volHeader {
 
 extern char *VSalvageMessage;  /* Canonical message when a volume is forced
                                 * offline */
-extern Volume *VGetVolume(Error * ec, Error * client_ec, VolId volumeId);
-extern Volume *VGetVolume_r(Error * ec, VolId volumeId);
+extern Volume *VGetVolume(Error * ec, Error * client_ec, VolumeId volumeId);
+extern Volume *VGetVolumeWithCall(Error * ec, Error * client_ec, VolumeId volumeId,
+                                  const struct timespec *ts, struct VCallByVol *cbv);
+extern Volume *VGetVolume_r(Error * ec, VolumeId volumeId);
 extern void VPutVolume(Volume *);
+extern void VPutVolumeWithCall(Volume *vp, struct VCallByVol *cbv);
 extern void VPutVolume_r(Volume *);
 extern void VOffline(Volume * vp, char *message);
 extern void VOffline_r(Volume * vp, char *message);
@@ -769,18 +796,19 @@ extern void VDisconnectFS_r(void);
 extern int VChildProcReconnectFS(void);
 extern Volume *VAttachVolume(Error * ec, VolumeId volumeId, int mode);
 extern Volume *VAttachVolume_r(Error * ec, VolumeId volumeId, int mode);
-extern Volume *VCreateVolume(Error * ec, char *partname, VolId volumeId,
-                            VolId parentId);
-extern Volume *VCreateVolume_r(Error * ec, char *partname, VolId volumeId,
-                              VolId parentId);
-extern VnodeId VAllocBitmapEntry(Error * ec, Volume * vp,
-                                struct vnodeIndex *index);
-extern VnodeId VAllocBitmapEntry_r(Error * ec, Volume * vp,
-                                  struct vnodeIndex *index, int flags);
-extern void VFreeBitMapEntry(Error * ec, register struct vnodeIndex *index,
+extern Volume *VCreateVolume(Error * ec, char *partname, VolumeId volumeId,
+                            VolumeId parentId);
+extern Volume *VCreateVolume_r(Error * ec, char *partname, VolumeId volumeId,
+                              VolumeId parentId);
+extern void VGrowBitmap(struct vnodeIndex *index);
+extern int VAllocBitmapEntry(Error * ec, Volume * vp,
+                            struct vnodeIndex *index);
+extern int VAllocBitmapEntry_r(Error * ec, Volume * vp,
+                              struct vnodeIndex *index, int flags);
+extern void VFreeBitMapEntry(Error * ec, Volume *vp, struct vnodeIndex *index,
                             unsigned bitNumber);
-extern void VFreeBitMapEntry_r(Error * ec, register struct vnodeIndex *index,
-                              unsigned bitNumber);
+extern void VFreeBitMapEntry_r(Error * ec, Volume *vp, struct vnodeIndex *index,
+                              unsigned bitNumber, int flags);
 extern int VolumeNumber(char *name);
 extern char *VolumeExternalName(VolumeId volumeId);
 extern int VolumeExternalName_r(VolumeId volumeId, char *name, size_t len);
@@ -798,8 +826,8 @@ extern void VDetachVolume(Error * ec, Volume * vp);
 extern void VDetachVolume_r(Error * ec, Volume * vp);
 extern void VForceOffline(Volume * vp);
 extern void VForceOffline_r(Volume * vp, int flags);
-extern void VBumpVolumeUsage(register Volume * vp);
-extern void VBumpVolumeUsage_r(register Volume * vp);
+extern void VBumpVolumeUsage(Volume * vp);
+extern void VBumpVolumeUsage_r(Volume * vp);
 extern void VSetDiskUsage(void);
 extern void VPrintCacheStats(void);
 extern void VReleaseVnodeFiles_r(Volume * vp);
@@ -812,26 +840,30 @@ extern int VInitAttachVolumes(ProgramType pt);
 extern void DiskToVolumeHeader(VolumeHeader_t * h, VolumeDiskHeader_t * dh);
 extern void VolumeHeaderToDisk(VolumeDiskHeader_t * dh, VolumeHeader_t * h);
 extern void AssignVolumeName(VolumeDiskData * vol, char *name, char *ext);
-extern void VTakeOffline_r(register Volume * vp);
-extern void VTakeOffline(register Volume * vp);
-extern Volume * VLookupVolume_r(Error * ec, VolId volumeId, Volume * hint);
-extern void VGetVolumePath(Error * ec, VolId volumeId, char **partitionp,
+extern void VTakeOffline_r(Volume * vp);
+extern void VTakeOffline(Volume * vp);
+extern Volume * VLookupVolume_r(Error * ec, VolumeId volumeId, Volume * hint);
+extern void VGetVolumePath(Error * ec, VolumeId volumeId, char **partitionp,
                           char **namep);
 extern char *vol_DevName(dev_t adev, char *wpath);
+extern afs_int32 VIsGoingOffline(struct Volume *vp);
 
 struct VLockFile;
 extern void VLockFileInit(struct VLockFile *lf, const char *path);
+extern void VLockFileReinit(struct VLockFile *lf);
 extern int VLockFileLock(struct VLockFile *lf, afs_uint32 offset,
                          int locktype, int nonblock);
 extern void VLockFileUnlock(struct VLockFile *lf, afs_uint32 offset);
 
+extern int VSetVolHashSize(int logsize);
+
 #ifdef AFS_DEMAND_ATTACH_FS
 extern Volume *VPreAttachVolumeByName(Error * ec, char *partition, char *name);
 extern Volume *VPreAttachVolumeByName_r(Error * ec, char *partition, char *name);
-extern Volume *VPreAttachVolumeById_r(Error * ec, char * partition, 
-                                     VolId volumeId);
-extern Volume *VPreAttachVolumeByVp_r(Error * ec, struct DiskPartition64 * partp, 
-                                     Volume * vp, VolId volume_id);
+extern Volume *VPreAttachVolumeById_r(Error * ec, char * partition,
+                                     VolumeId volumeId);
+extern Volume *VPreAttachVolumeByVp_r(Error * ec, struct DiskPartition64 * partp,
+                                     Volume * vp, VolumeId volume_id);
 extern Volume *VGetVolumeByVp_r(Error * ec, Volume * vp);
 extern int VShutdownByPartition_r(struct DiskPartition64 * dp);
 extern int VShutdownVolume_r(Volume * vp);
@@ -844,7 +876,6 @@ extern int VDisconnectSALV_r(void);
 extern void VPrintExtendedCacheStats(int flags);
 extern void VPrintExtendedCacheStats_r(int flags);
 extern void VLRU_SetOptions(int option, afs_uint32 val);
-extern int VSetVolHashSize(int logsize);
 extern int VRequestSalvage_r(Error * ec, Volume * vp, int reason, int flags);
 extern int VUpdateSalvagePriority_r(Volume * vp);
 extern int VRegisterVolOp_r(Volume * vp, FSSYNC_VolOp_info * vopinfo);
@@ -852,7 +883,9 @@ extern int VDeregisterVolOp_r(Volume * vp);
 extern void VCancelReservation_r(Volume * vp);
 extern int VChildProcReconnectFS_r(void);
 extern void VOfflineForVolOp_r(Error *ec, Volume *vp, char *message);
+#endif /* AFS_DEMAND_ATTACH_FS */
 
+#ifdef AFS_DEMAND_ATTACH_FS
 struct VDiskLock;
 extern void VDiskLockInit(struct VDiskLock *dl, struct VLockFile *lf,
                           afs_uint32 offset);
@@ -860,6 +893,7 @@ extern int VGetDiskLock(struct VDiskLock *dl, int locktype, int nonblock);
 extern void VReleaseDiskLock(struct VDiskLock *dl, int locktype);
 #endif /* AFS_DEMAND_ATTACH_FS */
 extern int VVolOpLeaveOnline_r(Volume * vp, FSSYNC_VolOp_info * vopinfo);
+extern int VVolOpLeaveOnlineNoHeader_r(Volume * vp, FSSYNC_VolOp_info * vopinfo);
 extern int VVolOpSetVBusy_r(Volume * vp, FSSYNC_VolOp_info * vopinfo);
 
 extern void VPurgeVolume(Error * ec, Volume * vp);
@@ -867,6 +901,7 @@ extern void VPurgeVolume(Error * ec, Volume * vp);
 extern afs_int32 VCanScheduleSalvage(void);
 extern afs_int32 VCanUseFSSYNC(void);
 extern afs_int32 VCanUseSALVSYNC(void);
+extern afs_int32 VCanUnsafeAttach(void);
 extern afs_int32 VReadVolumeDiskHeader(VolumeId volid,
                                       struct DiskPartition64 * dp,
                                       VolumeDiskHeader_t * hdr);
@@ -974,9 +1009,15 @@ extern int VWalkVolumeHeaders(struct DiskPartition64 *dp, const char *partpath,
 /* VAllocBitmapEntry_r flags */
 #define VOL_ALLOC_BITMAP_WAIT    0x1  /* for demand attach, wait for other exclusive ops to end */
 
+/* VFreeBitMapEntry_r flags */
+#define VOL_FREE_BITMAP_WAIT     0x1  /* for demand attach, wait for other exclusive ops to end */
+
 /* VRequestSalvage_r flags */
-#define VOL_SALVAGE_INVALIDATE_HEADER 0x1 /* for demand attach fs, invalidate volume header cache */
+#define VOL_SALVAGE_NO_OFFLINE        0x1 /* we do not need to wait to offline the volume; it has
+                                           * not been fully attached */
 
+#define VOLUME_BITMAP_GROWSIZE  16     /* bytes, => 128vnodes */
+                                       /* Must be a multiple of 4 (1 word) !! */
 
 #if    defined(NEARINODE_HINT)
 #define V_pref(vp,nearInode)  nearInodeHash(V_id(vp),(nearInode)); (nearInode) %= V_partition(vp)->f_files
@@ -984,8 +1025,8 @@ extern int VWalkVolumeHeaders(struct DiskPartition64 *dp, const char *partpath,
 #define V_pref(vp,nearInode)   nearInode = 0
 #endif /* NEARINODE_HINT */
 
-hdr_static_inline(unsigned int)
-afs_printable_VolumeId_u(VolumeId d) { return (unsigned int) d; }
+hdr_static_inline(unsigned long)
+afs_printable_VolumeId_lu(VolumeId d) { return (unsigned long) (d); }
 
 hdr_static_inline(unsigned int)
 afs_printable_VnodeId_u(VnodeId d) { return (unsigned int) d; }