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
This commit is contained in:
Konstantin Belousov 2011-01-25 14:04:02 +00:00
parent 96410b9575
commit dbccdf7684

View File

@ -1337,13 +1337,14 @@ vtruncbuf(struct vnode *vp, struct ucred *cred, struct thread *td,
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 @@ vtruncbuf(struct vnode *vp, struct ucred *cred, struct thread *td,
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);
}
}