diff options
Diffstat (limited to 'sys/ufs/ffs/ffs_vfsops.c')
-rw-r--r-- | sys/ufs/ffs/ffs_vfsops.c | 33 |
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. */ |