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.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index cf0e220..c40be45 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -908,7 +908,7 @@ ffs_sync(mp, waitfor, cred, p)
struct inode *ip;
struct ufsmount *ump = VFSTOUFS(mp);
struct fs *fs;
- int error, allerror = 0;
+ int error, count, wait, lockreq, allerror = 0;
fs = ump->um_fs;
if (fs->fs_fmod != 0 && fs->fs_ronly != 0) { /* XXX */
@@ -918,6 +918,12 @@ ffs_sync(mp, waitfor, cred, p)
/*
* Write back each (modified) inode.
*/
+ wait = 0;
+ lockreq = LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK;
+ if (waitfor == MNT_WAIT) {
+ wait = 1;
+ lockreq = LK_EXCLUSIVE | LK_INTERLOCK;
+ }
simple_lock(&mntvnode_slock);
loop:
for (vp = mp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) {
@@ -938,9 +944,7 @@ loop:
}
if (vp->v_type != VCHR) {
simple_unlock(&mntvnode_slock);
- error =
- vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK, p);
- if (error) {
+ if ((error = vget(vp, lockreq, p)) != 0) {
simple_lock(&mntvnode_slock);
if (error == ENOENT)
goto loop;
@@ -948,14 +952,12 @@ loop:
}
if ((error = VOP_FSYNC(vp, cred, waitfor, p)) != 0)
allerror = error;
- VOP_UNLOCK(vp, 0, p);
- vrele(vp);
+ vput(vp);
simple_lock(&mntvnode_slock);
} else {
simple_unlock(&mntvnode_slock);
simple_unlock(&vp->v_interlock);
- /* UFS_UPDATE(vp, waitfor == MNT_WAIT); */
- UFS_UPDATE(vp, 0);
+ UFS_UPDATE(vp, wait);
simple_lock(&mntvnode_slock);
}
}
@@ -963,9 +965,16 @@ loop:
/*
* Force stale file system control information to be flushed.
*/
- if (waitfor != MNT_LAZY) {
- if (ump->um_mountp->mnt_flag & MNT_SOFTDEP)
- waitfor = MNT_NOWAIT;
+ if (waitfor == MNT_WAIT) {
+ if ((error = softdep_flushworklist(ump->um_mountp, &count, p)))
+ allerror = error;
+ /* Flushed work items may create new vnodes to clean */
+ if (count) {
+ simple_lock(&mntvnode_slock);
+ goto loop;
+ }
+ }
+ if (waitfor == MNT_NOWAIT) {
vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY, p);
if ((error = VOP_FSYNC(ump->um_devvp, cred, waitfor, p)) != 0)
allerror = error;
OpenPOWER on IntegriCloud