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.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 0204613..b3292d0 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -1351,9 +1351,10 @@ ffs_flushfiles(mp, flags, td)
struct thread *td;
{
struct ufsmount *ump;
- int error;
+ int qerror, error;
ump = VFSTOUFS(mp);
+ qerror = 0;
#ifdef QUOTA
if (mp->mnt_flag & MNT_QUOTA) {
int i;
@@ -1361,11 +1362,19 @@ ffs_flushfiles(mp, flags, td)
if (error)
return (error);
for (i = 0; i < MAXQUOTAS; i++) {
- quotaoff(td, mp, i);
+ error = quotaoff(td, mp, i);
+ if (error != 0) {
+ if ((flags & EARLYFLUSH) == 0)
+ return (error);
+ else
+ qerror = error;
+ }
}
+
/*
- * Here we fall through to vflush again to ensure
- * that we have gotten rid of all the system vnodes.
+ * Here we fall through to vflush again to ensure that
+ * we have gotten rid of all the system vnodes, unless
+ * quotas must not be closed.
*/
}
#endif
@@ -1380,11 +1389,21 @@ ffs_flushfiles(mp, flags, td)
* that we have gotten rid of all the system vnodes.
*/
}
- /*
- * Flush all the files.
+
+ /*
+ * Do not close system files if quotas were not closed, to be
+ * able to sync the remaining dquots. The freeblks softupdate
+ * workitems might hold a reference on a dquot, preventing
+ * quotaoff() from completing. Next round of
+ * softdep_flushworklist() iteration should process the
+ * blockers, allowing the next run of quotaoff() to finally
+ * flush held dquots.
+ *
+ * Otherwise, flush all the files.
*/
- if ((error = vflush(mp, 0, flags, td)) != 0)
+ if (qerror == 0 && (error = vflush(mp, 0, flags, td)) != 0)
return (error);
+
/*
* Flush filesystem metadata.
*/
OpenPOWER on IntegriCloud