]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
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>
Tue, 8 Mar 2011 12:16:04 +0000 (04:16 -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.

Reviewed-on: http://gerrit.openafs.org/4058
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
(cherry picked from commit 08ffe3e81d875b58ae5fe4c5733845d5132913a0)

Change-Id: I0336bbc543828237cb9ae97ede18133b4e15100a
Reviewed-on: http://gerrit.openafs.org/4168
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 a111cc7a69a38e09ef5849633ff6896ed298a0ae..c453409c320c7a52947e658820e168ed9b453d31 100644 (file)
@@ -810,7 +810,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);
@@ -928,6 +928,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)))
@@ -1377,8 +1383,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 bc379e60c71501386b1609431a1e960dd326d8e0..530925ea405e88949b47eea5ecf65036767b7c0e 100644 (file)
@@ -5833,32 +5833,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 da961a6284da53803a658609659d4172d3544e46..e6742eda4d56e3a0f7457bad85036a2ddbac56cb 100644 (file)
@@ -788,10 +788,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);
@@ -988,6 +988,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