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);
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)))
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++;
}
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;
}
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);
/* 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