DAFS: Wait for exclusive ops in VFreeBitMapEntry_r
authorAndrew Deason <adeason@sinenomine.net>
Fri, 25 Feb 2011 20:43:09 +0000 (14:43 -0600)
committerDerrick Brashear <shadow@dementia.org>
Fri, 4 Mar 2011 15:37:23 +0000 (07:37 -0800)
VAllocBitmapEntry_r puts the volume in an exclusive state and drops
VOL_LOCK when traversing the volume bitmap and updating the bitmap.
So, VFreeBitMapEntry_r must ensure the volume is not in an exclusive
state, to make sure that VAllocBitmapEntry_r is not updating the
bitmap at the same time. Do so, by waiting for the volume to come out
of exclusive state at the beginning of VFreeBitMapEntry_r.

Change-Id: I5fdd344e4d9d12451fd65a767fa5672c8be70a39
Reviewed-on: http://gerrit.openafs.org/4058
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementia.org>

src/vol/vnode.c
src/vol/volume.c
src/vol/volume.h

index 42270c3..3c10baa 100644 (file)
@@ -813,7 +813,7 @@ VAllocVnode_r(Error * ec, Volume * vp, VnodeType type)
            if (fdP)
                FDH_CLOSE(fdP);
            VOL_LOCK;
-           VFreeBitMapEntry_r(&tmp, &vp->vnodeIndex[class], bitNumber);
+           VFreeBitMapEntry_r(&tmp, vp, &vp->vnodeIndex[class], bitNumber, 0 /*flags*/);
            VInvalidateVnode_r(vnp);
            VnUnlock(vnp, WRITE_LOCK);
            VnCancelReservation_r(vnp);
@@ -931,6 +931,12 @@ VnLoad(Error * ec, Volume * vp, Vnode * vnp,
            unsigned int bitNumber = vnodeIdToBitNumber(Vn_id(vnp));
            unsigned int offset = bitNumber >> 3;
 
+#ifdef AFS_DEMAND_ATTACH_FS
+           /* Make sure the volume bitmap isn't getting updated while we are
+            * checking it */
+           VWaitExclusiveState_r(vp);
+#endif
+
            /* Test to see if vnode number is valid. */
            if ((offset >= index->bitmapSize)
                || ((*(index->bitmap + offset) & (1 << (bitNumber & 0x7)))
@@ -1380,8 +1386,9 @@ VPutVnode_r(Error * ec, Vnode * vnp)
                if (vnp->delete && !*ec) {
                    if (Vn_volume(vnp)->header->diskstuff.filecount-- < 1)
                        Vn_volume(vnp)->header->diskstuff.filecount = 0;
-                   VFreeBitMapEntry_r(ec, &vp->vnodeIndex[class],
-                                      vnodeIdToBitNumber(Vn_id(vnp)));
+                   VFreeBitMapEntry_r(ec, vp, &vp->vnodeIndex[class],
+                                      vnodeIdToBitNumber(Vn_id(vnp)),
+                                      VOL_FREE_BITMAP_WAIT);
                }
            }
            vcp->writes++;
index 5b9f348..1217ec6 100644 (file)
@@ -6311,32 +6311,50 @@ VAllocBitmapEntry(Error * ec, Volume * vp, struct vnodeIndex * index)
 }
 
 void
-VFreeBitMapEntry_r(Error * ec, struct vnodeIndex *index,
-                  unsigned bitNumber)
+VFreeBitMapEntry_r(Error * ec, Volume *vp, struct vnodeIndex *index,
+                  unsigned bitNumber, int flags)
 {
     unsigned int offset;
 
     *ec = 0;
+
+#ifdef AFS_DEMAND_ATTACH_FS
+    if (flags & VOL_FREE_BITMAP_WAIT) {
+       /* VAllocBitmapEntry_r allocs bitmap entries under an exclusive volume
+        * state, so ensure we're not in an exclusive volume state when we update
+        * the bitmap */
+       VCreateReservation_r(vp);
+       VWaitExclusiveState_r(vp);
+    }
+#endif
+
 #ifdef BITMAP_LATER
     if (!index->bitmap)
-       return;
+       goto done;
 #endif /* BITMAP_LATER */
+
     offset = bitNumber >> 3;
     if (offset >= index->bitmapSize) {
        *ec = VNOVNODE;
-       return;
+       goto done;
     }
     if (offset < index->bitmapOffset)
        index->bitmapOffset = offset & ~3;      /* Truncate to nearest bit32 */
     *(index->bitmap + offset) &= ~(1 << (bitNumber & 0x7));
+
+ done:
+#ifdef AFS_DEMAND_ATTACH_FS
+    VCancelReservation_r(vp);
+#endif
+    return; /* make the compiler happy for non-DAFS */
 }
 
 void
-VFreeBitMapEntry(Error * ec, struct vnodeIndex *index,
+VFreeBitMapEntry(Error * ec, Volume *vp, struct vnodeIndex *index,
                 unsigned bitNumber)
 {
     VOL_LOCK;
-    VFreeBitMapEntry_r(ec, index, bitNumber);
+    VFreeBitMapEntry_r(ec, vp, index, bitNumber, VOL_FREE_BITMAP_WAIT);
     VOL_UNLOCK;
 }
 
index 598283e..e4dad3c 100644 (file)
@@ -822,10 +822,10 @@ 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, struct vnodeIndex *index,
+extern void VFreeBitMapEntry(Error * ec, Volume *vp, struct vnodeIndex *index,
                             unsigned bitNumber);
-extern void VFreeBitMapEntry_r(Error * ec, 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);
@@ -1023,6 +1023,9 @@ 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        0x2 /* we do not need to wait to offline the volume; it has