Index: sys/fs/nandfs/nandfs_segment.c =================================================================== --- sys/fs/nandfs/nandfs_segment.c +++ sys/fs/nandfs/nandfs_segment.c @@ -479,6 +479,7 @@ struct nandfs_node *nandfs_node; struct vnode *vp, *mvp; struct thread *td; + struct bufobj *bo; int error, update; td = curthread; @@ -499,17 +500,21 @@ update = 1; } + bo = &vp->v_bufobj; + BO_LOCK(bo); if (vp->v_bufobj.bo_dirty.bv_cnt) { error = nandfs_iterate_dirty_buf(vp, seginfo, 0); if (error) { nandfs_error("%s: cannot iterate vnode:%p " "err:%d\n", __func__, vp, error); vput(vp); + BO_UNLOCK(bo); return (error); } update = 1; } else vput(vp); + BO_UNLOCK(bo); if (update) nandfs_node_update(nandfs_node); Index: sys/fs/nfsclient/nfs_clvfsops.c =================================================================== --- sys/fs/nfsclient/nfs_clvfsops.c +++ sys/fs/nfsclient/nfs_clvfsops.c @@ -1628,6 +1628,7 @@ { struct vnode *vp, *mvp; struct thread *td; + struct bufobj *bo; int error, allerror = 0; td = curthread; @@ -1649,12 +1650,15 @@ */ loop: MNT_VNODE_FOREACH_ALL(vp, mp, mvp) { - /* XXX Racy bv_cnt check. */ + bo = &vp->v_bufobj; + BO_LOCK(bo); if (NFSVOPISLOCKED(vp) || vp->v_bufobj.bo_dirty.bv_cnt == 0 || waitfor == MNT_LAZY) { + BO_UNLOCK(bo); VI_UNLOCK(vp); continue; } + BO_UNLOCK(bo); if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) { MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp); goto loop; Index: sys/kern/vfs_default.c =================================================================== --- sys/kern/vfs_default.c +++ sys/kern/vfs_default.c @@ -1198,6 +1198,7 @@ struct vnode *vp, *mvp; struct thread *td; int error, lockreq, allerror = 0; + struct bufobj *bo; td = curthread; lockreq = LK_EXCLUSIVE | LK_INTERLOCK; @@ -1208,10 +1209,14 @@ */ loop: MNT_VNODE_FOREACH_ALL(vp, mp, mvp) { + bo = &vp->v_bufobj; + BO_LOCK(bo); if (vp->v_bufobj.bo_dirty.bv_cnt == 0) { + BO_UNLOCK(bo); VI_UNLOCK(vp); continue; } + BO_UNLOCK(bo); if ((error = vget(vp, lockreq, td)) != 0) { if (error == ENOENT) { MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);