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:
parent
96410b9575
commit
dbccdf7684
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user