summaryrefslogtreecommitdiffstats
path: root/sys/ufs/ffs/ffs_vfsops.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/ufs/ffs/ffs_vfsops.c')
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index ad4c24d..d080fbb 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -1001,10 +1001,10 @@ ffs_sync(mp, waitfor, cred, td)
* Write back each (modified) inode.
*/
wait = 0;
- lockreq = LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK;
+ lockreq = LK_EXCLUSIVE | LK_NOWAIT;
if (waitfor == MNT_WAIT) {
wait = 1;
- lockreq = LK_EXCLUSIVE | LK_INTERLOCK;
+ lockreq = LK_EXCLUSIVE;
}
mtx_lock(&mntvnode_mtx);
loop:
@@ -1015,34 +1015,40 @@ loop:
*/
if (vp->v_mount != mp)
goto loop;
- nvp = TAILQ_NEXT(vp, v_nmntvnodes);
- mtx_unlock(&mntvnode_mtx);
- mtx_lock(&vp->v_interlock);
+ /*
+ * Depend on the mntvnode_slock to keep things stable enough
+ * for a quick test. Since there might be hundreds of
+ * thousands of vnodes, we cannot afford even a subroutine
+ * call unless there's a good chance that we have work to do.
+ */
+ nvp = TAILQ_NEXT(vp, v_nmntvnodes);
ip = VTOI(vp);
if (vp->v_type == VNON || ((ip->i_flag &
- (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 &&
- TAILQ_EMPTY(&vp->v_dirtyblkhd))) {
- mtx_unlock(&vp->v_interlock);
- mtx_lock(&mntvnode_mtx);
+ (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 &&
+ TAILQ_EMPTY(&vp->v_dirtyblkhd))) {
continue;
}
if (vp->v_type != VCHR) {
+ mtx_unlock(&mntvnode_mtx);
if ((error = vget(vp, lockreq, td)) != 0) {
mtx_lock(&mntvnode_mtx);
if (error == ENOENT)
goto loop;
- continue;
+ } else {
+ if ((error = VOP_FSYNC(vp, cred, waitfor, td)) != 0)
+ allerror = error;
+ VOP_UNLOCK(vp, 0, td);
+ vrele(vp);
+ mtx_lock(&mntvnode_mtx);
}
- if ((error = VOP_FSYNC(vp, cred, waitfor, td)) != 0)
- allerror = error;
- VOP_UNLOCK(vp, 0, td);
- vrele(vp);
} else {
- mtx_unlock(&vp->v_interlock);
+ mtx_unlock(&mntvnode_mtx);
UFS_UPDATE(vp, wait);
+ mtx_lock(&mntvnode_mtx);
}
- mtx_lock(&mntvnode_mtx);
+ if (TAILQ_NEXT(vp, v_nmntvnodes) != nvp)
+ goto loop;
}
mtx_unlock(&mntvnode_mtx);
/*
OpenPOWER on IntegriCloud