From: Andrew Deason Date: Fri, 25 Feb 2011 20:43:09 +0000 (-0600) Subject: DAFS: Wait for exclusive ops in VFreeBitMapEntry_r X-Git-Tag: openafs-devel-1_7_1~857 X-Git-Url: http://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=08ffe3e81d875b58ae5fe4c5733845d5132913a0;hp=a862d2df93fd4e8c8c7a0b8eebe9e59b75f54072 DAFS: Wait for exclusive ops in VFreeBitMapEntry_r 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 Reviewed-by: Derrick Brashear --- diff --git a/src/vol/vnode.c b/src/vol/vnode.c index 42270c3..3c10baa 100644 --- a/src/vol/vnode.c +++ b/src/vol/vnode.c @@ -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++; diff --git a/src/vol/volume.c b/src/vol/volume.c index 5b9f348..1217ec6 100644 --- a/src/vol/volume.c +++ b/src/vol/volume.c @@ -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; } diff --git a/src/vol/volume.h b/src/vol/volume.h index 598283e..e4dad3c 100644 --- a/src/vol/volume.h +++ b/src/vol/volume.h @@ -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