diff options
author | jeff <jeff@FreeBSD.org> | 2003-03-13 07:22:53 +0000 |
---|---|---|
committer | jeff <jeff@FreeBSD.org> | 2003-03-13 07:22:53 +0000 |
commit | ec5374265bec154d9330f861f2a089de4212a69d (patch) | |
tree | 2ff99f4d38da5eeda65501fdabc5b354222043a5 /sys/kern/vfs_subr.c | |
parent | ae3c8799daed67832db23a2957d5f5e47250cad9 (diff) | |
download | FreeBSD-src-ec5374265bec154d9330f861f2a089de4212a69d.zip FreeBSD-src-ec5374265bec154d9330f861f2a089de4212a69d.tar.gz |
- Remove a dead check for bp->b_vp == vp in vtruncbuf(). This has not been
possible for some time.
- Lock the buf before accessing fields. This should very rarely be locked.
- Assert that B_DELWRI is set after we acquire the buf. This should always
be the case now.
Diffstat (limited to 'sys/kern/vfs_subr.c')
-rw-r--r-- | sys/kern/vfs_subr.c | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 3cedcb4..0c3d003 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -1345,21 +1345,24 @@ restart: restartsync: for (bp = TAILQ_FIRST(&vp->v_dirtyblkhd); bp; bp = nbp) { nbp = TAILQ_NEXT(bp, b_vnbufs); - if ((bp->b_flags & B_DELWRI) && (bp->b_lblkno < 0)) { - if (BUF_LOCK(bp, - LK_EXCLUSIVE | LK_SLEEPFAIL | LK_INTERLOCK, - VI_MTX(vp)) == ENOLCK) - goto restart; - bremfree(bp); - if (bp->b_vp == vp) - bp->b_flags |= B_ASYNC; - else - bp->b_flags &= ~B_ASYNC; - - BUF_WRITE(bp); - VI_LOCK(vp); - goto restartsync; + if (bp->b_lblkno > 0) + continue; + /* + * Since we hold the vnode lock this should only + * fail if we're racing with the buf daemon. + */ + if (BUF_LOCK(bp, + LK_EXCLUSIVE | LK_SLEEPFAIL | LK_INTERLOCK, + VI_MTX(vp)) == ENOLCK) { + goto restart; } + KASSERT((bp->b_flags & B_DELWRI), + ("buf(%p) on dirty queue without DELWRI.", bp)); + + bremfree(bp); + bawrite(bp); + VI_LOCK(vp); + goto restartsync; } } |