aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/vfs_subr.c
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2011-01-25 14:04:02 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2011-01-25 14:04:02 +0000
commitdbccdf7684ccc5943a0891785bb9e224f23561c1 (patch)
tree093b441cf3b6d8b21afc0ee8d155cf2be895e457 /sys/kern/vfs_subr.c
parent96410b95758bde268b864d881f94604df3956c7a (diff)
downloadsrc-dbccdf7684ccc5943a0891785bb9e224f23561c1.tar.gz
src-dbccdf7684ccc5943a0891785bb9e224f23561c1.zip
When vtruncbuf() iterates over the vnode buffer list, lock buffer object
before checking the validity of the next buffer pointer. Otherwise, the buffer might be reclaimed after the check, causing iteration to run into wrong buffer. Reported and tested by: pho MFC after: 1 week
Notes
Notes: svn path=/head/; revision=217824
Diffstat (limited to 'sys/kern/vfs_subr.c')
-rw-r--r--sys/kern/vfs_subr.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index a9012ca46f9f..58061b4e250c 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -1337,13 +1337,14 @@ restart:
brelse(bp);
anyfreed = 1;
+ BO_LOCK(bo);
if (nbp != NULL &&
(((nbp->b_xflags & BX_VNCLEAN) == 0) ||
(nbp->b_vp != vp) ||
(nbp->b_flags & B_DELWRI))) {
+ BO_UNLOCK(bo);
goto restart;
}
- BO_LOCK(bo);
}
TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) {
@@ -1360,13 +1361,15 @@ restart:
bp->b_flags &= ~B_ASYNC;
brelse(bp);
anyfreed = 1;
+
+ BO_LOCK(bo);
if (nbp != NULL &&
(((nbp->b_xflags & BX_VNDIRTY) == 0) ||
(nbp->b_vp != vp) ||
(nbp->b_flags & B_DELWRI) == 0)) {
+ BO_UNLOCK(bo);
goto restart;
}
- BO_LOCK(bo);
}
}