diff options
author | tegge <tegge@FreeBSD.org> | 2005-09-16 18:28:12 +0000 |
---|---|---|
committer | tegge <tegge@FreeBSD.org> | 2005-09-16 18:28:12 +0000 |
commit | 63fab0fe2d627784fac90b843f392304beef139d (patch) | |
tree | 46d6e8d013b890dd15e9f0d61e54718cf39810e0 | |
parent | 2bc1b3a58302c0e550ac5894f297b9d7e3f1cc4a (diff) | |
download | FreeBSD-src-63fab0fe2d627784fac90b843f392304beef139d.zip FreeBSD-src-63fab0fe2d627784fac90b843f392304beef139d.tar.gz |
Break out of loop if next buffer pointer has become invalid while flushing
current buffer.
Reviewed by: kan
-rw-r--r-- | sys/kern/vfs_subr.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 77714e0..3486b0c 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -1081,6 +1081,8 @@ flushbuflist(bufv, flags, bo, slpflag, slptimeo) { struct buf *bp, *nbp; int retval, error; + daddr_t lblkno; + b_xflags_t xflags; ASSERT_BO_LOCKED(bo); @@ -1090,6 +1092,13 @@ flushbuflist(bufv, flags, bo, slpflag, slptimeo) ((flags & V_ALT) && (bp->b_xflags & BX_ALTDATA) == 0)) { continue; } + lblkno = 0; + xflags = 0; + if (nbp != NULL) { + lblkno = nbp->b_lblkno; + xflags = nbp->b_xflags & + (BX_BKGRDMARKER | BX_VNDIRTY | BX_VNCLEAN); + } retval = EAGAIN; error = BUF_TIMELOCK(bp, LK_EXCLUSIVE | LK_SLEEPFAIL | LK_INTERLOCK, BO_MTX(bo), @@ -1125,6 +1134,12 @@ flushbuflist(bufv, flags, bo, slpflag, slptimeo) bp->b_flags &= ~B_ASYNC; brelse(bp); BO_LOCK(bo); + if (nbp != NULL && + (nbp->b_bufobj != bo || + nbp->b_lblkno != lblkno || + (nbp->b_xflags & + (BX_BKGRDMARKER | BX_VNDIRTY | BX_VNCLEAN)) != xflags)) + break; /* nbp invalid */ } return (retval); } |