diff options
Diffstat (limited to 'sys/kern')
-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); } |