summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortegge <tegge@FreeBSD.org>2006-01-09 19:32:21 +0000
committertegge <tegge@FreeBSD.org>2006-01-09 19:32:21 +0000
commitcecb9f6b7be918ffcd172fb9edabcef2556d94ad (patch)
tree3a11a58e06c62590cb770b351cc82401b75c602c
parent0c586bcaf4832a0c517c967ae2b98e63f3bf473b (diff)
downloadFreeBSD-src-cecb9f6b7be918ffcd172fb9edabcef2556d94ad.zip
FreeBSD-src-cecb9f6b7be918ffcd172fb9edabcef2556d94ad.tar.gz
If the lock passed to getdirtybuf() is the softdep lock then the background
write completed wakeup could be missed. Close the race by grabbing the lock normally used for protection of bp->b_xflags. Reviewed by: truckman
-rw-r--r--sys/ufs/ffs/ffs_softdep.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index 088b4fe..d60fe11 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -5901,6 +5901,19 @@ getdirtybuf(bp, mtx, waitfor)
return (NULL);
}
if ((bp->b_vflags & BV_BKGRDINPROG) != 0) {
+ if (mtx == &lk && waitfor == MNT_WAIT) {
+ mtx_unlock(mtx);
+ BO_LOCK(bp->b_bufobj);
+ BUF_UNLOCK(bp);
+ if ((bp->b_vflags & BV_BKGRDINPROG) != 0) {
+ bp->b_vflags |= BV_BKGRDWAIT;
+ msleep(&bp->b_xflags, BO_MTX(bp->b_bufobj),
+ PRIBIO | PDROP, "getbuf", 0);
+ } else
+ BO_UNLOCK(bp->b_bufobj);
+ mtx_lock(mtx);
+ return (NULL);
+ }
BUF_UNLOCK(bp);
if (waitfor != MNT_WAIT)
return (NULL);
OpenPOWER on IntegriCloud