diff options
author | tegge <tegge@FreeBSD.org> | 2006-01-09 19:32:21 +0000 |
---|---|---|
committer | tegge <tegge@FreeBSD.org> | 2006-01-09 19:32:21 +0000 |
commit | cecb9f6b7be918ffcd172fb9edabcef2556d94ad (patch) | |
tree | 3a11a58e06c62590cb770b351cc82401b75c602c | |
parent | 0c586bcaf4832a0c517c967ae2b98e63f3bf473b (diff) | |
download | FreeBSD-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.c | 13 |
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); |