diff options
author | Grigoriy Orlov <gluk@cvs.openbsd.org> | 2001-09-10 08:48:43 +0000 |
---|---|---|
committer | Grigoriy Orlov <gluk@cvs.openbsd.org> | 2001-09-10 08:48:43 +0000 |
commit | 60d5f3573fef0e8bd3308dd339a5de6195fbb33a (patch) | |
tree | 8a3d4536794f8f4d7b68b6bebc88a9da2f83c09d | |
parent | 3d8a07c4d7807081d3e435f655dfe9d5b86f697a (diff) |
Mark buffers with dependencies as B_DEFERRED and skip them one time
when doing sync. From FreeBSD.
art@ ok.
-rw-r--r-- | sys/sys/buf.h | 3 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_vnops.c | 18 |
2 files changed, 19 insertions, 2 deletions
diff --git a/sys/sys/buf.h b/sys/sys/buf.h index 5aa361e7563..1bd2c267cef 100644 --- a/sys/sys/buf.h +++ b/sys/sys/buf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: buf.h,v 1.26 2001/08/30 12:41:14 gluk Exp $ */ +/* $OpenBSD: buf.h,v 1.27 2001/09/10 08:48:42 gluk Exp $ */ /* $NetBSD: buf.h,v 1.25 1997/04/09 21:12:17 mycroft Exp $ */ /* @@ -150,6 +150,7 @@ struct buf { #define B_XXX 0x02000000 /* Debugging flag. */ #define B_VFLUSH 0x04000000 /* Buffer is being synced. */ #define B_SCANNED 0x08000000 /* Block already pushed during sync */ +#define B_DEFERRED 0x10000000 /* Skipped over for cleaning */ /* * This structure describes a clustered I/O. It is stored in the b_saveaddr diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c index 3dac84c2203..dae8b5c9528 100644 --- a/sys/ufs/ffs/ffs_vnops.c +++ b/sys/ufs/ffs/ffs_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ffs_vnops.c,v 1.18 2001/06/27 04:58:48 art Exp $ */ +/* $OpenBSD: ffs_vnops.c,v 1.19 2001/09/10 08:48:42 gluk Exp $ */ /* $NetBSD: ffs_vnops.c,v 1.7 1996/05/11 18:27:24 mycroft Exp $ */ /* @@ -251,12 +251,28 @@ loop: bp->b_flags &= ~B_SCANNED; for (bp = LIST_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { nbp = LIST_NEXT(bp, b_vnbufs); + /* + * Reasons to skip this buffer: it has already been considered + * on this pass, this pass is the first time through on a + * synchronous flush request and the buffer being considered + * is metadata, the buffer has dependencies that will cause + * it to be redirtied and it has not already been deferred, + * or it is already being written. + */ if (bp->b_flags & (B_BUSY | B_SCANNED)) continue; if ((bp->b_flags & B_DELWRI) == 0) panic("ffs_fsync: not dirty"); if (skipmeta && bp->b_lblkno < 0) continue; + if (ap->a_waitfor != MNT_WAIT && + LIST_FIRST(&bp->b_dep) != NULL && + (bp->b_flags & B_DEFERRED) == 0 && + buf_countdeps(bp, 0, 1)) { + bp->b_flags |= B_DEFERRED; + continue; + } + bremfree(bp); bp->b_flags |= B_BUSY | B_SCANNED; splx(s); |