summaryrefslogtreecommitdiffstats
path: root/sys
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 /sys
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
Diffstat (limited to 'sys')
-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