]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
vol: Allow VAllocVnode of specific vnodes
authorMarc Dionne <marc.c.dionne@gmail.com>
Sat, 21 Jan 2012 19:42:01 +0000 (14:42 -0500)
committerDerrick Brashear <shadow@dementix.org>
Tue, 10 Apr 2012 19:15:32 +0000 (12:15 -0700)
Add parameters to VAllocVnode to allow the caller to specifiy the
vnode and unique numbers to use.  This will be used by the RW
replication code to keep vnode numbers in sync between the master
volume and the replicas.

Adapted from code by Vishal Powar and Derrick Brashear.

Change-Id: Ibaf79aad2b3e7a52802f5e01f7e4c7730c3f5090
Reviewed-on: http://gerrit.openafs.org/6672
Reviewed-by: Derrick Brashear <shadow@dementix.org>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
src/viced/afsfileprocs.c
src/vol/vnode.c
src/vol/vnode.h
src/vol/volume.c
src/vol/volume.h

index c2658ff9e15764b8336eff448b6dd3e979654891..43039f4457651908f7789b8bfc712c4366d10ac4 100644 (file)
@@ -1806,7 +1806,7 @@ Alloc_NewVnode(Vnode * parentptr, DirHandle * dir, Volume * volptr,
        return VSALVAGE;
     }
 
-    *targetptr = VAllocVnode(&errorCode, volptr, FileType);
+    *targetptr = VAllocVnode(&errorCode, volptr, FileType, 0, 0);
     if (errorCode != 0) {
        VAdjustDiskUsage(&temp, volptr, -BlocksPreallocatedForVnode, 0);
        return (errorCode);
index 37b697f453694097bf2938266624a1d10e7a7dc1..39e7978357bc4fbb9c67e8eb371a46bb17d06ac6 100644 (file)
@@ -556,11 +556,11 @@ VLookupVnode(Volume * vp, VnodeId vnodeId)
 
 
 Vnode *
-VAllocVnode(Error * ec, Volume * vp, VnodeType type)
+VAllocVnode(Error * ec, Volume * vp, VnodeType type, VnodeId in_vnode, Unique in_unique)
 {
     Vnode *retVal;
     VOL_LOCK;
-    retVal = VAllocVnode_r(ec, vp, type);
+    retVal = VAllocVnode_r(ec, vp, type, in_vnode, in_unique);
     VOL_UNLOCK;
     return retVal;
 }
@@ -571,6 +571,8 @@ VAllocVnode(Error * ec, Volume * vp, VnodeType type)
  * @param[out] ec    error code return
  * @param[in]  vp    volume object pointer
  * @param[in]  type  desired vnode type
+ * @param[in]  type  desired vnode ID (optional)
+ * @param[in]  type  desired vnode Unique (optional)
  *
  * @return vnode object pointer
  *
@@ -580,7 +582,7 @@ VAllocVnode(Error * ec, Volume * vp, VnodeType type)
  * @post vnode allocated and returned
  */
 Vnode *
-VAllocVnode_r(Error * ec, Volume * vp, VnodeType type)
+VAllocVnode_r(Error * ec, Volume * vp, VnodeType type, VnodeId in_vnode, Unique in_unique)
 {
     Vnode *vnp;
     VnodeId vnodeNumber;
@@ -588,6 +590,9 @@ VAllocVnode_r(Error * ec, Volume * vp, VnodeType type)
     struct VnodeClassInfo *vcp;
     VnodeClass class;
     Unique unique;
+    struct vnodeIndex *index;
+    unsigned int offset;
+
 #ifdef AFS_DEMAND_ATTACH_FS
     VolState vol_state_save;
 #endif
@@ -624,10 +629,6 @@ VAllocVnode_r(Error * ec, Volume * vp, VnodeType type)
        return NULL;
     }
 
-    unique = vp->nextVnodeUnique++;
-    if (!unique)
-       unique = vp->nextVnodeUnique++;
-
     if (vp->nextVnodeUnique > V_uniquifier(vp)) {
        VUpdateVolume_r(ec, vp, 0);
        if (*ec)
@@ -640,12 +641,63 @@ VAllocVnode_r(Error * ec, Volume * vp, VnodeType type)
            return NULL;
     }
 
-    /* Find a slot in the bit map */
-    bitNumber = VAllocBitmapEntry_r(ec, vp, &vp->vnodeIndex[class],
-                                   VOL_ALLOC_BITMAP_WAIT);
-    if (*ec)
-       return NULL;
-    vnodeNumber = bitNumberToVnodeNumber(bitNumber, class);
+    /*
+     * If in_vnode and in_unique are specified, we are asked to
+     * allocate a specifc vnode slot.  Used by RW replication to
+     * keep vnode IDs consistent with the master.
+     */
+
+    if (!in_vnode) {
+       unique = vp->nextVnodeUnique++;
+       if (!unique)
+           unique = vp->nextVnodeUnique++;
+
+       if (vp->nextVnodeUnique > V_uniquifier(vp)) {
+           VUpdateVolume_r(ec, vp, 0);
+           if (*ec)
+               return NULL;
+       }
+
+       /* Find a slot in the bit map */
+       bitNumber = VAllocBitmapEntry_r(ec, vp, &vp->vnodeIndex[class],
+               VOL_ALLOC_BITMAP_WAIT);
+
+       if (*ec)
+           return NULL;
+       vnodeNumber = bitNumberToVnodeNumber(bitNumber, class);
+    } else {
+       index = &vp->vnodeIndex[class];
+       if (!in_unique) {
+           *ec = VNOVNODE;
+           return NULL;
+       }
+       /* Catch us up to where the master is */
+       if (in_unique > vp->nextVnodeUnique)
+           vp->nextVnodeUnique = in_unique+1;
+
+       if (vp->nextVnodeUnique > V_uniquifier(vp)) {
+           VUpdateVolume_r(ec, vp, 0);
+           if (*ec)
+               return NULL;
+       }
+
+       unique = in_unique;
+       bitNumber = vnodeIdToBitNumber(in_vnode);
+       offset = bitNumber >> 3;
+
+       /* Mark vnode in use. Grow bitmap if needed. */
+       if ((offset >= index->bitmapSize)
+               || ((*(index->bitmap + offset) & (1 << (bitNumber & 0x7))) == 0))
+           VGrowBitmap(index);
+       /* Should not happen */
+       if (*(index->bitmap + offset) & (1 << (bitNumber & 0x7))) {
+           *ec = VNOVNODE;
+           return NULL;
+       }
+
+       *(index->bitmap + offset) |= (1 << (bitNumber & 0x7));
+       vnodeNumber = in_vnode;
+    }
 
     /*
      * DAFS:
index a374258c388709bfa41c086fc9a766d6b83d3f15..d0f2c1dd864c1b7d6da221244c34c2df24687435 100644 (file)
@@ -271,8 +271,11 @@ extern void VPutVnode(Error * ec, Vnode * vnp);
 extern void VPutVnode_r(Error * ec, Vnode * vnp);
 extern int VVnodeWriteToRead(Error * ec, Vnode * vnp);
 extern int VVnodeWriteToRead_r(Error * ec, Vnode * vnp);
-extern Vnode *VAllocVnode(Error * ec, struct Volume *vp, VnodeType type);
-extern Vnode *VAllocVnode_r(Error * ec, struct Volume *vp, VnodeType type);
+extern Vnode *VAllocVnode(Error * ec, struct Volume *vp, VnodeType type,
+       VnodeId in_vnode, Unique in_unique);
+extern Vnode *VAllocVnode_r(Error * ec, struct Volume *vp, VnodeType type,
+       VnodeId in_vnode, Unique in_unique);
+
 /*extern VFreeVnode();*/
 extern Vnode *VGetFreeVnode_r(struct VnodeClassInfo *vcp, struct Volume *vp,
                               VnodeId vnodeNumber);
index d846092458203f083b51c4f6505dc7e6df9c9b65..4dd86589c89ff8eb4f89a89962f60d596c327a36 100644 (file)
@@ -180,9 +180,6 @@ pthread_t vol_glock_holder = 0;
 #endif
 
 
-#define VOLUME_BITMAP_GROWSIZE 16      /* bytes, => 128vnodes */
-                                       /* Must be a multiple of 4 (1 word) !! */
-
 /* this parameter needs to be tunable at runtime.
  * 128 was really inadequate for largish servers -- at 16384 volumes this
  * puts average chain length at 128, thus an average 65 deref's to find a volptr.
@@ -6201,6 +6198,25 @@ VChildProcReconnectFS(void)
 /* volume bitmap routines                          */
 /***************************************************/
 
+/*
+ * Grow the bitmap by the defined increment
+ */
+void
+VGrowBitmap(struct vnodeIndex *index)
+{
+    byte *bp;
+
+    bp = realloc(index->bitmap, index->bitmapSize + VOLUME_BITMAP_GROWSIZE);
+    osi_Assert(bp != NULL);
+    index->bitmap = bp;
+    bp += index->bitmapSize;
+    memset(bp, 0, VOLUME_BITMAP_GROWSIZE);
+    index->bitmapOffset = index->bitmapSize;
+    index->bitmapSize += VOLUME_BITMAP_GROWSIZE;
+
+    return;
+}
+
 /**
  * allocate a vnode bitmap number for the vnode
  *
@@ -6322,14 +6338,8 @@ VAllocBitmapEntry_r(Error * ec, Volume * vp,
        bp += sizeof(bit32) /* i.e. 4 */ ;
     }
     /* No bit map entry--must grow bitmap */
-    bp = (byte *)
-       realloc(index->bitmap, index->bitmapSize + VOLUME_BITMAP_GROWSIZE);
-    osi_Assert(bp != NULL);
-    index->bitmap = bp;
-    bp += index->bitmapSize;
-    memset(bp, 0, VOLUME_BITMAP_GROWSIZE);
-    index->bitmapOffset = index->bitmapSize;
-    index->bitmapSize += VOLUME_BITMAP_GROWSIZE;
+    VGrowBitmap(index);
+    bp = index->bitmap;
     *bp = 1;
     ret = index->bitmapOffset * 8;
 #ifdef AFS_DEMAND_ATTACH_FS
index f9b647300ec2e03a610abeaaae4fe34a15776974..f5f24e51c29f471a5a7596bcfeb03f9216537f2a 100644 (file)
@@ -807,6 +807,7 @@ extern Volume *VCreateVolume(Error * ec, char *partname, VolId volumeId,
                             VolId parentId);
 extern Volume *VCreateVolume_r(Error * ec, char *partname, VolId volumeId,
                               VolId 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,
@@ -1021,6 +1022,8 @@ extern int VWalkVolumeHeaders(struct DiskPartition64 *dp, const char *partpath,
 #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