From 1c2ceb28808bb572cc88121aa451272fcaecca08 Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Thu, 13 Jan 2000 07:20:01 +0000 Subject: [PATCH] Because cylinder group blocks are now written in background, it is no longer sufficient to get a lock on a buffer to know that its write has been completed. We have to first get the lock on the buffer, then check to see if it is doing a background write. If it is doing background write, we have to wait for the background write to finish, then check to see if that fullfilled our dependency, and if not to start another write. Luckily the explanation is longer than the fix. --- sys/contrib/softupdates/ffs_softdep.c | 16 +++++++++++++--- sys/ufs/ffs/ffs_softdep.c | 16 +++++++++++++--- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/sys/contrib/softupdates/ffs_softdep.c b/sys/contrib/softupdates/ffs_softdep.c index db63d71672db..b2e2c62a5229 100644 --- a/sys/contrib/softupdates/ffs_softdep.c +++ b/sys/contrib/softupdates/ffs_softdep.c @@ -52,7 +52,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * from: @(#)ffs_softdep.c 9.49 (McKusick) 1/12/00 + * from: @(#)ffs_softdep.c 9.50 (McKusick) 1/12/00 * $FreeBSD$ */ @@ -4556,8 +4556,18 @@ getdirtybuf(bpp, waitfor) for (;;) { if ((bp = *bpp) == NULL) return (0); - if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT) == 0) - break; + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT) == 0) { + if ((bp->b_xflags & BX_BKGRDINPROG) == 0) + break; + BUF_UNLOCK(bp); + if (waitfor != MNT_WAIT) + return (0); + bp->b_xflags |= BX_BKGRDWAIT; + tsleep(&bp->b_xflags, PRIBIO, "getbuf", 0); + if (bp->b_xflags & BX_BKGRDINPROG) + panic("getdirtybuf: still writing"); + continue; + } if (waitfor != MNT_WAIT) return (0); FREE_LOCK_INTERLOCKED(&lk); diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index db63d71672db..b2e2c62a5229 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -52,7 +52,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * from: @(#)ffs_softdep.c 9.49 (McKusick) 1/12/00 + * from: @(#)ffs_softdep.c 9.50 (McKusick) 1/12/00 * $FreeBSD$ */ @@ -4556,8 +4556,18 @@ getdirtybuf(bpp, waitfor) for (;;) { if ((bp = *bpp) == NULL) return (0); - if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT) == 0) - break; + if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT) == 0) { + if ((bp->b_xflags & BX_BKGRDINPROG) == 0) + break; + BUF_UNLOCK(bp); + if (waitfor != MNT_WAIT) + return (0); + bp->b_xflags |= BX_BKGRDWAIT; + tsleep(&bp->b_xflags, PRIBIO, "getbuf", 0); + if (bp->b_xflags & BX_BKGRDINPROG) + panic("getdirtybuf: still writing"); + continue; + } if (waitfor != MNT_WAIT) return (0); FREE_LOCK_INTERLOCKED(&lk);