Add code for locking individual volumes on disk
[openafs.git] / src / vol / partition.h
index e104fca..15ee14c 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 Sine Nomine Associates
  */
 
 /*
@@ -14,6 +16,9 @@
 
  */
 
+#ifndef AFS_VOL_PARTITION_H
+#define AFS_VOL_PARTITION_H
+
 #include <afs/param.h>
 #include "nfs.h"
 #if    defined(AFS_HPUX_ENV)
@@ -27,6 +32,9 @@
 #define        AFS_RDSKDEV     "/dev/r"
 #endif
 
+#include "lock.h"
+
+
 /* All Vice partitions on a server will have the following name prefix */
 #define VICE_PARTITION_PREFIX  "/vicep"
 #define VICE_PREFIX_SIZE       (sizeof(VICE_PARTITION_PREFIX)-1)
 #define VICE_ALWAYSATTACH_FILE "AlwaysAttach"
 #endif
 
+/**
+ * abstraction for files used for file-locking.
+ */
+struct VLockFile {
+    FD_t fd;                /**< fd holding the lock(s) */
+    char *path;             /**< path to the lock file */
+    int refcount;           /**< how many locks we have on the file */
+
+#ifdef AFS_PTHREAD_ENV
+    pthread_mutex_t mutex;  /**< lock for the VLockFile struct */
+#endif /* AFS_PTHREAD_ENV */
+};
+
+#ifdef AFS_DEMAND_ATTACH_FS
+/*
+ * flag bits for 'flags' in struct VDiskLock.
+ */
+#define VDISKLOCK_ACQUIRING  0x1   /**< is someone waiting for an fs lock? */
+#define VDISKLOCK_ACQUIRED   0x2   /**< we have an fs lock */
+
+/**
+ * on-disk locking mechanism.
+ */
+struct VDiskLock {
+    struct VLockFile *lockfile; /**< file holding the locks */
+    afs_uint32 offset;          /**< what offset we lock in the file */
+
+    struct Lock rwlock;         /**< rw lock for inter-thread locking */
+    pthread_mutex_t mutex;      /**< lock for the DiskLock object itself */
+    pthread_cond_t cv;          /**< cond var for 'acquiring' changes */
+
+    int lockers;                /**< # of callers that have this locked; */
+
+    unsigned int flags;         /**< see above for flag bits */
+};
+#endif /* AFS_DEMAND_ATTACH_FS */
+
+
 /* For NT, the roles of "name" and "devName" are reversed. That is, "name"
  * refers to the drive letter name and "devName" refers to the /vicep style
  * or name. The reason for this is that a lot of places assume that "name"
  * variant for VGetPartition as well. Also, the VolPartitionInfo RPC does
  * a swap before sending the data out on the wire.
  */
-struct DiskPartition {
-    struct DiskPartition *next;
+struct DiskPartition64 {
+    struct DiskPartition64 *next;
     char *name;                        /* Mounted partition name */
     char *devName;             /* Device mounted on */
     Device device;             /* device number */
-    int lock_fd;               /* File descriptor of this partition if locked; otherwise -1;
+    afs_int32 index;            /* partition index (0<=x<=VOLMAXPARTS) */
+    FD_t lock_fd;              /* File descriptor of this partition if locked; otherwise -1;
                                 * Not used by the file server */
-    int free;                  /* Total number of blocks (1K) presumed
+    afs_int64 free;            /* Total number of blocks (1K) presumed
                                 * available on this partition (accounting
                                 * for the minfree parameter for the
                                 * partition).  This is adjusted
@@ -65,7 +112,7 @@ struct DiskPartition {
                                 * this is recomputed.  This number can
                                 * be negative, if the partition starts
                                 * out too full */
-    int totalUsable;           /* Total number of blocks available on this
+    afs_int64 totalUsable;     /* Total number of blocks available on this
                                 * partition, taking into account the minfree
                                 * parameter for the partition (see the
                                 * 4.2bsd command tunefs, but note that the
@@ -73,11 +120,34 @@ struct DiskPartition {
                                 * is not reread--does not apply here.  The
                                 * superblock is re-read periodically by
                                 * VSetPartitionDiskUsage().) */
-    int minFree;               /* Number blocks to be kept free, as last read
+    afs_int64 minFree;         /* Number blocks to be kept free, as last read
                                 * from the superblock */
     int flags;
-    int f_files;               /* total number of files in this partition */
+    afs_int64 f_files;         /* total number of files in this partition */
+#ifdef AFS_DEMAND_ATTACH_FS
+    struct {
+       struct rx_queue head;   /* list of volumes on this partition (VByPList) */
+       afs_uint32 len;         /* length of volume list */
+       int busy;               /* asynch vol list op in progress */
+       pthread_cond_t cv;      /* vol_list.busy change cond var */
+    } vol_list;
+    struct VLockFile headerLockFile;
+    struct VDiskLock headerLock; /* lock for the collective headers on the partition */
+
+    struct VLockFile volLockFile; /* lock file for individual volume locks */
+#endif /* AFS_DEMAND_ATTACH_FS */
+};
+
+struct DiskPartitionStats64 {
+    afs_int64 free;
+    afs_int64 totalUsable;
+    afs_int64 minFree;
+    afs_int64 f_files;
+#ifdef AFS_DEMAND_ATTACH_FS
+    afs_int32 vol_list_len;
+#endif
 };
+
 #define        PART_DONTUPDATE 1
 #define PART_DUPLICATE  2      /* NT - used if we find more than one partition 
                                 * using the same drive. Will be dumped before
@@ -90,8 +160,17 @@ extern int VValidVPTEntry(struct vptab *vptp);
 #endif
 
 
-extern struct DiskPartition *DiskPartitionList;
-extern struct DiskPartition *VGetPartition();
+struct Volume;                 /* Potentially forward definition */
+
+extern struct DiskPartition64 *DiskPartitionList;
+extern struct DiskPartition64 *VGetPartition(char * name, int abortp);
+extern struct DiskPartition64 *VGetPartition_r(char * name, int abortp);
+#ifdef AFS_DEMAND_ATTACH_FS
+extern struct DiskPartition64 *VGetPartitionById(afs_int32 index, int abortp);
+extern struct DiskPartition64 *VGetPartitionById_r(afs_int32 index, int abortp);
+extern int VPartHeaderLock(struct DiskPartition64 *dp, int locktype);
+extern void VPartHeaderUnlock(struct DiskPartition64 *dp, int locktype);
+#endif
 extern int VAttachPartitions(void);
 extern void VLockPartition(char *name);
 extern void VLockPartition_r(char *name);
@@ -99,9 +178,13 @@ extern void VUnlockPartition(char *name);
 extern void VUnlockPartition_r(char *name);
 extern void VResetDiskUsage(void);
 extern void VResetDiskUsage_r(void);
-extern void VSetPartitionDiskUsage(register struct DiskPartition *dp);
-extern void VSetPartitionDiskUsage_r(register struct DiskPartition *dp);
-extern char *VPartitionPath(struct DiskPartition *p);
-/*extern void VAdjustDiskUsage(Error *ec, Volume *vp, afs_int32 blocks,
-                            afs_int32 checkBlocks); */
+extern void VSetPartitionDiskUsage(register struct DiskPartition64 *dp);
+extern void VSetPartitionDiskUsage_r(register struct DiskPartition64 *dp);
+extern char *VPartitionPath(struct DiskPartition64 *p);
+extern void VAdjustDiskUsage(Error * ec, struct Volume *vp,
+                            afs_sfsize_t blocks, afs_sfsize_t checkBlocks);
+extern int VDiskUsage(struct Volume *vp, afs_sfsize_t blocks);
 extern void VPrintDiskStats(void);
+extern int VInitPartitionPackage(void);
+
+#endif /* AFS_VOL_PARTITION_H */