dafs-accurately-track-inuse-20080317
[openafs.git] / src / vol / volume.h
index f0d1403..cbf0881 100644 (file)
@@ -5,6 +5,8 @@
  * 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
+ *
+ * Portions Copyright (c) 2006-2008 Sine Nomine Associates
  */
 
 /*
 #define VolumeWriteable2(vol)          (vol.type == readwriteVolume)
 typedef bit32 FileOffset;      /* Offset in this file */
 #define Date afs_uint32
+#include "daemon_com.h"
+#include "fssync.h"
+
+#if 0
+/** turn this on if you suspect a volume package locking bug */
+#define VOL_LOCK_DEBUG 1
+#endif
+
+#ifdef VOL_LOCK_DEBUG
+#define VOL_LOCK_ASSERT_HELD \
+    assert(vol_glock_holder == pthread_self())
+#define VOL_LOCK_ASSERT_UNHELD \
+    assert(vol_glock_holder == 0)
+#define _VOL_LOCK_SET_HELD \
+    vol_glock_holder = pthread_self()
+#define _VOL_LOCK_SET_UNHELD \
+    vol_glock_holder = 0
+#define VOL_LOCK_DBG_CV_WAIT_END \
+    do { \
+        VOL_LOCK_ASSERT_UNHELD; \
+        _VOL_LOCK_SET_HELD; \
+    } while(0)
+#define VOL_LOCK_DBG_CV_WAIT_BEGIN \
+    do { \
+         VOL_LOCK_ASSERT_HELD; \
+         _VOL_LOCK_SET_UNHELD; \
+    } while(0)
+#else
+#define VOL_LOCK_ASSERT_HELD
+#define VOL_LOCK_ASSERT_UNHELD
+#define VOL_LOCK_DBG_CV_WAIT_BEGIN
+#define VOL_LOCK_DBG_CV_WAIT_END
+#endif
+
 
 #ifdef AFS_PTHREAD_ENV
 #include <assert.h>
 #include <pthread.h>
 extern pthread_mutex_t vol_glock_mutex;
-extern pthread_mutex_t vol_attach_mutex;
+extern pthread_mutex_t vol_trans_mutex;
 extern pthread_cond_t vol_put_volume_cond;
 extern pthread_cond_t vol_sleep_cond;
-#define VATTACH_LOCK \
-    assert(pthread_mutex_lock(&vol_attach_mutex) == 0);
-#define VATTACH_UNLOCK \
-    assert(pthread_mutex_unlock(&vol_attach_mutex) == 0);
+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(); \
+    } while (0)
+#define VOL_UNLOCK \
+    do { \
+        VOL_LOCK_ASSERT_HELD; \
+        vol_glock_holder = 0; \
+        assert(pthread_mutex_unlock(&vol_glock_mutex) == 0); \
+    } while (0)
+#define VOL_CV_WAIT(cv) \
+    do { \
+        VOL_LOCK_DBG_CV_WAIT_BEGIN; \
+        assert(pthread_cond_wait((cv), &vol_glock_mutex) == 0); \
+        VOL_LOCK_DBG_CV_WAIT_END; \
+    } while (0)
+#else /* !VOL_LOCK_DEBUG */
 #define VOL_LOCK \
-    assert(pthread_mutex_lock(&vol_glock_mutex) == 0);
+    assert(pthread_mutex_lock(&vol_glock_mutex) == 0)
 #define VOL_UNLOCK \
-    assert(pthread_mutex_unlock(&vol_glock_mutex) == 0);
+    assert(pthread_mutex_unlock(&vol_glock_mutex) == 0)
+#define VOL_CV_WAIT(cv) assert(pthread_cond_wait((cv), &vol_glock_mutex) == 0)
+#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)
 #else /* AFS_PTHREAD_ENV */
-#define VATTACH_LOCK
-#define VATTACH_UNLOCK
 #define VOL_LOCK
 #define VOL_UNLOCK
+#define VSALVSYNC_LOCK
+#define VSALVSYNC_UNLOCK
+#define VTRANS_LOCK
+#define VTRANS_UNLOCK
 #endif /* AFS_PTHREAD_ENV */
 
-typedef enum { fileServer, volumeUtility, salvager } ProgramType;
+/**
+ * volume package program type enumeration.
+ */
+typedef enum {
+    fileServer          = 1,    /**< the fileserver process */
+    volumeUtility       = 2,    /**< volserver, or a 
+                                *   single volume salvager (non-dafs) */
+    salvager            = 3,    /**< standalone whole-partition salvager */
+    salvageServer       = 4,    /**< dafs online salvager */
+    debugUtility        = 5     /**< fssync-debug or similar utility */
+} ProgramType;
 extern ProgramType programType;        /* The type of program using the package */
 
 /* Some initialization parameters for the volume package */
@@ -56,12 +132,99 @@ extern int (*V_BreakVolumeCallbacks) ();
 extern int (*vol_PollProc) ();
 #define        DOPOLL  ((vol_PollProc)? (*vol_PollProc)() : 0)
 
+#ifdef AFS_DEMAND_ATTACH_FS
+/**
+ * variable error return code based upon programType and DAFS presence
+ */
+#define DAFS_VSALVAGE   ((programType == fileServer) ? VSALVAGING : VSALVAGE)
+#else
+#define DAFS_VSALVAGE   (VSALVAGE)
+#endif
+
 struct versionStamp {          /* Version stamp for critical volume files */
     bit32 magic;               /* Magic number */
     bit32 version;             /* Version number of this file, or software
                                 * that created this file */
 };
 
+#ifdef AFS_DEMAND_ATTACH_FS
+/**
+ * demand attach volume state enumeration.
+ *
+ * @note values must be contiguous in order for VIsValidState() to work correctly
+ */
+typedef enum {
+    VOL_STATE_UNATTACHED        = 0,    /**< volume is unattached */
+    VOL_STATE_PREATTACHED       = 1,    /**< volume has been pre-attached */
+    VOL_STATE_ATTACHING         = 2,    /**< volume is transitioning to fully attached */
+    VOL_STATE_ATTACHED          = 3,    /**< volume has been fully attached */
+    VOL_STATE_UPDATING          = 4,    /**< volume is updating on-disk structures */
+    VOL_STATE_GET_BITMAP        = 5,    /**< volume is getting bitmap entries */
+    VOL_STATE_HDR_LOADING       = 6,    /**< volume is loading disk header */
+    VOL_STATE_HDR_ATTACHING     = 7,    /**< volume is getting a header from the LRU */
+    VOL_STATE_SHUTTING_DOWN     = 8,    /**< volume is shutting down */
+    VOL_STATE_GOING_OFFLINE     = 9,    /**< volume is going offline */
+    VOL_STATE_OFFLINING         = 10,   /**< volume is transitioning to offline */
+    VOL_STATE_DETACHING         = 11,   /**< volume is transitioning to detached */
+    VOL_STATE_SALVSYNC_REQ      = 12,   /**< volume is blocked on a salvsync request */
+    VOL_STATE_SALVAGING         = 13,   /**< volume is being salvaged */
+    VOL_STATE_ERROR             = 14,   /**< volume is in an error state */
+    VOL_STATE_VNODE_ALLOC       = 15,   /**< volume is busy allocating a new vnode */
+    VOL_STATE_VNODE_GET         = 16,   /**< volume is busy getting vnode disk data */
+    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 */
+    /* please add new states directly above this line */
+    VOL_STATE_FREED             = 20,   /**< debugging aid */
+    VOL_STATE_COUNT             = 21,   /**< total number of valid states */
+} VolState;
+
+/**
+ * V_attachFlags bits.
+ */
+enum VolFlags {
+    VOL_HDR_ATTACHED      = 0x1,     /**< volume header is attached to Volume struct */
+    VOL_HDR_LOADED        = 0x2,     /**< volume header contents are valid */
+    VOL_HDR_IN_LRU        = 0x4,     /**< volume header is in LRU */
+    VOL_IN_HASH           = 0x8,     /**< volume is in hash table */
+    VOL_ON_VBYP_LIST      = 0x10,    /**< volume is on VByP list */
+    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 */
+};
+
+/* VPrintExtendedCacheStats flags */
+#define VOL_STATS_PER_CHAIN   0x1  /**< compute simple per-chain stats */
+#define VOL_STATS_PER_CHAIN2  0x2  /**< compute per-chain stats that require scanning
+                                   *   every element of the chain */
+
+/* VLRU_SetOptions options */
+#define VLRU_SET_THRESH       1
+#define VLRU_SET_INTERVAL     2
+#define VLRU_SET_MAX          3
+#define VLRU_SET_ENABLED      4
+
+/**
+ * VLRU queue names.
+ */
+typedef enum {
+    VLRU_QUEUE_NEW        = 0,  /**< LRU queue for new volumes */
+    VLRU_QUEUE_MID        = 1,  /**< survivor generation */
+    VLRU_QUEUE_OLD        = 2,  /**< old generation */
+    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 */
+} VLRUQueueName;
+
+/* default scanner timing parameters */
+#define VLRU_DEFAULT_OFFLINE_THRESH (60*60*2) /* 2 hours */
+#define VLRU_DEFAULT_OFFLINE_INTERVAL (60*2) /* 2 minutes */
+#define VLRU_DEFAULT_OFFLINE_MAX 8 /* 8 volumes */
+
+#endif /* AFS_DEMAND_ATTACH_FS */
+
+
 /* Magic numbers and version stamps for each type of file */
 #define VOLUMEHEADERMAGIC      ((bit32)0x88a1bb3c)
 #define VOLUMEINFOMAGIC                ((bit32)0x78a1b2c5)
@@ -234,7 +397,8 @@ typedef struct VolumeDiskData {
                                 * of measurement; week[6] is 7 days ago */
     Date dayUseDate;           /* Date the dayUse statistics refer to; the week use stats
                                 * are the preceding 7 days */
-    int reserved3[11];         /* Other stats here */
+    unsigned int volUpdateCounter; /*incremented at every update of volume*/
+    int reserved3[10];         /* Other stats here */
 
     /* Server supplied dates */
     Date creationDate;         /* Creation date for a read/write
@@ -282,12 +446,147 @@ typedef struct VolumeDiskData {
 /**************************************/
 /* Memory resident volume information */
 /**************************************/
+
+/** 
+ * global volume package stats.
+ */
+typedef struct VolPkgStats {
+#ifdef AFS_DEMAND_ATTACH_FS
+    /*
+     * demand attach fs
+     * extended volume package statistics
+     */
+
+    /* levels */
+    afs_uint32 state_levels[VOL_STATE_COUNT]; /**< volume state transition counters */
+
+    /* counters */
+    afs_uint64 hash_looks;           /**< number of hash chain element traversals */
+    afs_uint64 hash_reorders;        /**< number of hash chain reorders */
+    afs_uint64 salvages;             /**< online salvages since fileserver start */
+    afs_uint64 vol_ops;              /**< volume operations since fileserver start */
+#endif /* AFS_DEMAND_ATTACH_FS */
+
+    afs_uint64 hdr_loads;            /**< header loads from disk */
+    afs_uint64 hdr_gets;             /**< header pulls out of LRU */
+    afs_uint64 attaches;             /**< volume attaches since fileserver start */
+    afs_uint64 soft_detaches;        /**< soft detach ops since fileserver start */
+
+    /* configuration parameters */
+    afs_uint32 hdr_cache_size;       /**< size of volume header cache */
+} VolPkgStats;
+extern VolPkgStats VStats;
+
+/*
+ * volume header cache supporting structures
+ */
+struct volume_hdr_LRU_stats {
+    afs_uint32 free;
+    afs_uint32 used;
+    afs_uint32 attached;
+};
+
+struct volume_hdr_LRU_t {
+    struct rx_queue lru;
+    struct volume_hdr_LRU_stats stats;
+};
+extern struct volume_hdr_LRU_t volume_hdr_LRU;
+
+/*
+ * volume hash chain supporting structures
+ */
+typedef struct VolumeHashChainHead {
+    struct rx_queue queue;
+    int len;
+    /* someday we could put a per-chain lock here... */
+#ifdef AFS_DEMAND_ATTACH_FS
+    int busy;
+    int cacheCheck;
+
+    /* per-chain statistics */
+    afs_uint64 looks;
+    afs_uint64 gets;
+    afs_uint64 reorders;
+
+    pthread_cond_t chain_busy_cv;
+#endif /* AFS_DEMAND_ATTACH_FS */
+} VolumeHashChainHead;
+
+typedef struct VolumeHashTable {
+    int Size;
+    int Mask;
+    VolumeHashChainHead * Table;
+} VolumeHashTable_t;
+extern VolumeHashTable_t VolumeHashTable;
+
+struct VolumeHashChainStats {
+    afs_int32 table_size;
+    afs_int32 chain_len;
+#ifdef AFS_DEMAND_ATTACH_FS
+    afs_int32 chain_cacheCheck;
+    afs_int32 chain_busy;
+    afs_uint64 chain_looks;
+    afs_uint64 chain_gets;
+    afs_uint64 chain_reorders;
+#endif
+};
+
+
+#ifdef AFS_DEMAND_ATTACH_FS
+/**
+ * DAFS extended per-volume statistics.
+ *
+ * @note this data lives across the entire
+ *       lifetime of the fileserver process
+ */
+typedef struct VolumeStats {
+    /* counters */
+    afs_uint64 hash_lookups;         /**< hash table lookups */
+    afs_uint64 hash_short_circuits;  /**< short circuited hash lookups (due to cacheCheck) */
+    afs_uint64 hdr_loads;            /**< header loads from disk */
+    afs_uint64 hdr_gets;             /**< header pulls out of LRU */
+    afs_uint16 attaches;             /**< attaches of this volume since fileserver start */
+    afs_uint16 soft_detaches;        /**< soft detaches of this volume */
+    afs_uint16 salvages;             /**< online salvages since fileserver start */
+    afs_uint16 vol_ops;              /**< volume operations since fileserver start */
+
+    /* timestamps */
+    afs_uint32 last_attach;      /**< unix timestamp of last VAttach */
+    afs_uint32 last_get;         /**< unix timestamp of last VGet/VHold */
+    afs_uint32 last_promote;     /**< unix timestamp of last VLRU promote/demote */
+    afs_uint32 last_hdr_get;     /**< unix timestamp of last GetVolumeHeader() */
+    afs_uint32 last_hdr_load;    /**< unix timestamp of last LoadVolumeHeader() */
+    afs_uint32 last_salvage;     /**< unix timestamp of last initiation of an online salvage */
+    afs_uint32 last_salvage_req; /**< unix timestamp of last SALVSYNC request */
+    afs_uint32 last_vol_op;      /**< unix timestamp of last volume operation */
+} VolumeStats;
+
+/**
+ * DAFS online salvager state.
+ */
+typedef struct VolumeOnlineSalvage {
+    afs_uint32 prio;            /**< number of VGetVolume's since salvage requested */
+    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 */
+} VolumeOnlineSalvage;
+
+/**
+ * DAFS Volume LRU state.
+ */
+typedef struct VolumeVLRUState {
+    struct rx_queue lru;        /**< VLRU queue for this generation */
+    VLRUQueueName idx;          /**< VLRU generation index */
+} VolumeVLRUState;
+#endif /* AFS_DEMAND_ATTACH_FS */
+
 typedef struct Volume {
-    struct Volume *hashNext;   /* Next in hash resolution table */
+    struct rx_queue q;          /* Volume hash chain pointers */
     VolumeId hashid;           /* Volume number -- for hash table lookup */
     struct volHeader *header;  /* Cached disk data */
     Device device;             /* Unix device for the volume */
-    struct DiskPartition
+    struct DiskPartition64
      *partition;               /* Information about the Unix partition */
     struct vnodeIndex {
        IHandle_t *handle;      /* Unix inode holding this index */
@@ -321,13 +620,28 @@ typedef struct Volume {
     byte specialStatus;                /* An error code to return on VGetVolume: the
                                 * volume is unavailable for the reason quoted,
                                 * currently VBUSY or VMOVED */
+    afs_uint32 checkoutMode;    /* for volume utilities, mode number for current checkout */
     afs_uint32 updateTime;     /* Time that this volume was put on the updated
                                 * 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 */
+#ifdef AFS_DEMAND_ATTACH_FS
+    VolState attach_state;      /* what stage of attachment has been completed */
+    afs_uint32 attach_flags;    /* flags related to attachment state */
+    pthread_cond_t attach_cv;   /* state change condition variable */
+    short nWaiters;             /* volume package internal ref count */
+    int chainCacheCheck;        /* Volume hash chain cache check */
+    struct rx_queue vol_list;   /* per-partition volume list (VByPList) */
+
+    VolumeOnlineSalvage salvage;  /* online salvager state */
+    VolumeStats stats;            /* per-volume statistics */
+    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 */
 } Volume;
 
 struct volHeader {
-    struct volHeader *prev, *next;     /* LRU pointers */
+    struct rx_queue lru;
     VolumeDiskData diskstuff;  /* General volume info read from disk */
     Volume *back;              /* back pointer to current volume structure */
 };
@@ -341,6 +655,12 @@ struct volHeader {
 #define V_vnodeIndex(vp)       ((vp)->vnodeIndex)
 #define V_nextVnodeUnique(vp)  ((vp)->nextVnodeUnique)
 #define V_linkHandle(vp)       ((vp)->linkHandle)
+#define V_checkoutMode(vp)      ((vp)->checkoutMode)
+#ifdef AFS_DEMAND_ATTACH_FS
+#define V_attachState(vp)       ((vp)->attach_state)
+#define V_attachFlags(vp)       ((vp)->attach_flags)
+#define V_attachCV(vp)          ((vp)->attach_cv)
+#endif /* AFS_DEMAND_ATTACH_FS */
 
 /* N.B. V_id must be this, rather than vp->id, or some programs will break, probably */
 #define V_stamp(vp)            ((vp)->header->diskstuff.stamp)
@@ -388,6 +708,7 @@ struct volHeader {
 #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)
 
 /* File offset computations.  The offset values in the volume header are
    computed with these macros -- when the file is written only!! */
@@ -398,7 +719,7 @@ struct volHeader {
 
 extern char *VSalvageMessage;  /* Canonical message when a volume is forced
                                 * offline */
-extern Volume *VGetVolume(Error * ec, VolId volumeId);
+extern Volume *VGetVolume(Error * ec, Error * client_ec, VolId volumeId);
 extern Volume *VGetVolume_r(Error * ec, VolId volumeId);
 extern void VPutVolume(Volume *);
 extern void VPutVolume_r(Volume *);
@@ -406,6 +727,9 @@ extern void VOffline(Volume * vp, char *message);
 extern void VOffline_r(Volume * vp, char *message);
 extern int VConnectFS(void);
 extern int VConnectFS_r(void);
+extern void VDisconnectFS(void);
+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,
@@ -415,7 +739,7 @@ extern Volume *VCreateVolume_r(Error * ec, char *partname, VolId volumeId,
 extern VnodeId VAllocBitmapEntry(Error * ec, Volume * vp,
                                 struct vnodeIndex *index);
 extern VnodeId VAllocBitmapEntry_r(Error * ec, Volume * vp,
-                                  struct vnodeIndex *index);
+                                  struct vnodeIndex *index, int flags);
 extern void VFreeBitMapEntry(Error * ec, register struct vnodeIndex *index,
                             unsigned bitNumber);
 extern void VFreeBitMapEntry_r(Error * ec, register struct vnodeIndex *index,
@@ -428,32 +752,63 @@ extern Volume *VAttachVolumeByName_r(Error * ec, char *partition, char *name,
                                     int mode);
 extern void VShutdown(void);
 extern void VUpdateVolume(Error * ec, Volume * vp);
-extern void VUpdateVolume_r(Error * ec, Volume * vp);
+extern void VUpdateVolume_r(Error * ec, Volume * vp, int flags);
 extern void VAddToVolumeUpdateList(Error * ec, Volume * vp);
 extern void VAddToVolumeUpdateList_r(Error * ec, Volume * vp);
 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);
+extern void VForceOffline_r(Volume * vp, int flags);
 extern void VBumpVolumeUsage(register Volume * vp);
 extern void VBumpVolumeUsage_r(register Volume * vp);
 extern void VSetDiskUsage(void);
 extern void VPrintCacheStats(void);
 extern void VReleaseVnodeFiles_r(Volume * vp);
 extern void VCloseVnodeFiles_r(Volume * vp);
-extern struct DiskPartition *VGetPartition(char *name, int abortp);
-extern struct DiskPartition *VGetPartition_r(char *name, int abortp);
-extern int VInitVolumePackage(ProgramType pt, int nLargeVnodes,
-                             int nSmallVnodes, int connect, int volcache);
+extern struct DiskPartition64 *VGetPartition(char *name, int abortp);
+extern struct DiskPartition64 *VGetPartition_r(char *name, int abortp);
+extern int VInitVolumePackage(ProgramType pt, afs_uint32 nLargeVnodes,
+                             afs_uint32 nSmallVnodes, int connect, afs_uint32 volcache);
 extern void DiskToVolumeHeader(VolumeHeader_t * h, VolumeDiskHeader_t * dh);
 extern void VolumeHeaderToDisk(VolumeDiskHeader_t * dh, VolumeHeader_t * h);
+extern void VTakeOffline_r(register Volume * vp);
+extern void VTakeOffline(register Volume * vp);
+extern Volume * VLookupVolume_r(Error * ec, VolId volumeId, Volume * hint);
+
+#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 *VGetVolumeByVp_r(Error * ec, Volume * vp);
+extern int VShutdownByPartition_r(struct DiskPartition64 * dp);
+extern int VShutdownVolume_r(Volume * vp);
+extern int VConnectSALV(void);
+extern int VConnectSALV_r(void);
+extern int VReconnectSALV(void);
+extern int VReconnectSALV_r(void);
+extern int VDisconnectSALV(void);
+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 VRegisterVolOp_r(Volume * vp, FSSYNC_VolOp_info * vopinfo);
+extern int VDeregisterVolOp_r(Volume * vp);
+extern void VCancelReservation_r(Volume * vp);
+#endif /* AFS_DEMAND_ATTACH_FS */
+extern int VVolOpLeaveOnline_r(Volume * vp, FSSYNC_VolOp_info * vopinfo);
+extern int VVolOpSetVBusy_r(Volume * vp, FSSYNC_VolOp_info * vopinfo);
 
 
 /* Naive formula relating number of file size to number of 1K blocks in file */
 /* Note:  we charge 1 block for 0 length files so the user can't store
    an inifite number of them; for most files, we give him the inode, vnode,
    and indirect block overhead, for FREE! */
-#define nBlocks(bytes) ((bytes) == 0? 1: ((bytes)+1023)/1024)
+#define nBlocks(bytes) ((afs_sfsize_t)((bytes) == 0? 1: (((afs_sfsize_t)(bytes))+1023)/1024))
 
 /* Client process id -- file server sends a Check volumes signal back to the client at this pid */
 #define CLIENTPID      "/vice/vol/clientpid"
@@ -476,6 +831,31 @@ extern void VolumeHeaderToDisk(VolumeDiskHeader_t * dh, VolumeHeader_t * h);
                                 * never knows about more than one copy of the same volume--when
                                 * a volume is moved from one partition to another on a single
                                 * server */
+#define V_PEEK     6           /* "Peek" at the volume without telling the fileserver.  This is
+                                * similar to V_SECRETLY, but read-only.  It is used in cases where
+                                * not impacting fileserver performance is more important than
+                                * getting the most recent data. */
+
+
+
+/* VUpdateVolume_r flags */
+#define VOL_UPDATE_WAIT          0x1  /* for demand attach, wait for other exclusive ops to end */
+#define VOL_UPDATE_NOFORCEOFF    0x2  /* don't force offline on failure. this is to prevent
+                                      * infinite recursion between vupdate and vforceoff */
+
+/* VForceOffline_r flags */
+#define VOL_FORCEOFF_NOUPDATE    0x1  /* don't force update on forceoff. this is to prevent
+                                      * infinite recursion between vupdate and vforceoff */
+
+/* VSyncVolume_r flags */
+#define VOL_SYNC_WAIT            0x1  /* for demand attach, wait for other exclusive ops to end */
+
+/* VAllocBitmapEntry_r flags */
+#define VOL_ALLOC_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 */
+
 
 #if    defined(NEARINODE_HINT)
 #define V_pref(vp,nearInode)  nearInodeHash(V_id(vp),(nearInode)); (nearInode) %= V_partition(vp)->f_files