summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authortegge <tegge@FreeBSD.org>2005-09-16 18:28:12 +0000
committertegge <tegge@FreeBSD.org>2005-09-16 18:28:12 +0000
commit63fab0fe2d627784fac90b843f392304beef139d (patch)
tree46d6e8d013b890dd15e9f0d61e54718cf39810e0 /sys
parent2bc1b3a58302c0e550ac5894f297b9d7e3f1cc4a (diff)
downloadFreeBSD-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
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/vfs_subr.c15
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);
}
OpenPOWER on IntegriCloud