diff options
author | jhb <jhb@FreeBSD.org> | 2001-06-28 03:50:17 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2001-06-28 03:50:17 +0000 |
commit | 54c05ef2f2ac9b7b4b641808d5ca5a0dbeef7a6a (patch) | |
tree | d94cf199c4a7049b5e10cd020dcee3d2cf8a1011 /sys/fs/nwfs | |
parent | fe47a79f92a98691f51822ae0a94e572b069d46e (diff) | |
download | FreeBSD-src-54c05ef2f2ac9b7b4b641808d5ca5a0dbeef7a6a.zip FreeBSD-src-54c05ef2f2ac9b7b4b641808d5ca5a0dbeef7a6a.tar.gz |
Protect the mnt_vnode list with the mntvnode lock.
Diffstat (limited to 'sys/fs/nwfs')
-rw-r--r-- | sys/fs/nwfs/nwfs_vfsops.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/sys/fs/nwfs/nwfs_vfsops.c b/sys/fs/nwfs/nwfs_vfsops.c index b37a856..2fb0752 100644 --- a/sys/fs/nwfs/nwfs_vfsops.c +++ b/sys/fs/nwfs/nwfs_vfsops.c @@ -471,30 +471,41 @@ nwfs_sync(mp, waitfor, cred, p) struct ucred *cred; struct proc *p; { - struct vnode *vp; + struct vnode *vp, *nvp; int error, allerror = 0; /* * Force stale buffer cache information to be flushed. */ + mtx_lock(&mntvnode_mtx); loop: for (vp = LIST_FIRST(&mp->mnt_vnodelist); vp != NULL; - vp = LIST_NEXT(vp, v_mntvnodes)) { + vp = nvp) { /* * If the vnode that we are about to sync is no longer * associated with this mount point, start over. */ if (vp->v_mount != mp) goto loop; + nvp = LIST_NEXT(vp, v_mntvnodes); + mtx_unlock(&mntvnode_mtx); + mtx_lock(&vp->v_interlock); if (VOP_ISLOCKED(vp, NULL) || TAILQ_EMPTY(&vp->v_dirtyblkhd) || - waitfor == MNT_LAZY) + waitfor == MNT_LAZY) { + mtx_unlock(&vp->v_interlock); + mtx_lock(&mntvnode_mtx); continue; - if (vget(vp, LK_EXCLUSIVE, p)) + } + if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p)) { + mtx_lock(&mntvnode_mtx); goto loop; + } error = VOP_FSYNC(vp, cred, waitfor, p); if (error) allerror = error; vput(vp); + mtx_lock(&mntvnode_mtx); } + mtx_unlock(&mntvnode_mtx); return (allerror); } |