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.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 7d48fdb..02c3eaf 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -952,7 +952,7 @@ ffs_sync(mp, waitfor, cred, p)
struct ucred *cred;
struct proc *p;
{
- struct vnode *nvp, *vp;
+ struct vnode *nvp, *vp, *devvp;
struct inode *ip;
struct ufsmount *ump = VFSTOUFS(mp);
struct fs *fs;
@@ -1026,12 +1026,21 @@ loop:
#ifdef QUOTA
qsync(mp);
#endif
- if (waitfor != MNT_LAZY) {
- vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY, p);
- if ((error = VOP_FSYNC(ump->um_devvp, cred, waitfor, p)) != 0)
+ devvp = ump->um_devvp;
+ mtx_lock(&devvp->v_interlock);
+ if (waitfor != MNT_LAZY &&
+ (devvp->v_numoutput > 0 || TAILQ_FIRST(&devvp->v_dirtyblkhd))) {
+ mtx_unlock(&devvp->v_interlock);
+ vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
+ if ((error = VOP_FSYNC(devvp, cred, waitfor, p)) != 0)
allerror = error;
- VOP_UNLOCK(ump->um_devvp, 0, p);
- }
+ VOP_UNLOCK(devvp, 0, p);
+ if (waitfor == MNT_WAIT) {
+ mtx_lock(&mntvnode_mtx);
+ goto loop;
+ }
+ } else
+ mtx_unlock(&devvp->v_interlock);
/*
* Write back modified superblock.
*/
OpenPOWER on IntegriCloud