|
@@ -2404,6 +2404,7 @@ static void ext4_orphan_cleanup(struct super_block *sb,
|
|
|
unsigned int s_flags = sb->s_flags;
|
|
|
int ret, nr_orphans = 0, nr_truncates = 0;
|
|
|
#ifdef CONFIG_QUOTA
|
|
|
+ int quota_update = 0;
|
|
|
int i;
|
|
|
#endif
|
|
|
if (!es->s_last_orphan) {
|
|
@@ -2442,14 +2443,32 @@ static void ext4_orphan_cleanup(struct super_block *sb,
|
|
|
#ifdef CONFIG_QUOTA
|
|
|
/* Needed for iput() to work correctly and not trash data */
|
|
|
sb->s_flags |= MS_ACTIVE;
|
|
|
- /* Turn on journaled quotas so that they are updated correctly */
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Turn on quotas which were not enabled for read-only mounts if
|
|
|
+ * filesystem has quota feature, so that they are updated correctly.
|
|
|
+ */
|
|
|
+ if (ext4_has_feature_quota(sb) && (s_flags & MS_RDONLY)) {
|
|
|
+ int ret = ext4_enable_quotas(sb);
|
|
|
+
|
|
|
+ if (!ret)
|
|
|
+ quota_update = 1;
|
|
|
+ else
|
|
|
+ ext4_msg(sb, KERN_ERR,
|
|
|
+ "Cannot turn on quotas: error %d", ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Turn on journaled quotas used for old sytle */
|
|
|
for (i = 0; i < EXT4_MAXQUOTAS; i++) {
|
|
|
if (EXT4_SB(sb)->s_qf_names[i]) {
|
|
|
int ret = ext4_quota_on_mount(sb, i);
|
|
|
- if (ret < 0)
|
|
|
+
|
|
|
+ if (!ret)
|
|
|
+ quota_update = 1;
|
|
|
+ else
|
|
|
ext4_msg(sb, KERN_ERR,
|
|
|
"Cannot turn on journaled "
|
|
|
- "quota: error %d", ret);
|
|
|
+ "quota: type %d: error %d", i, ret);
|
|
|
}
|
|
|
}
|
|
|
#endif
|
|
@@ -2510,10 +2529,12 @@ static void ext4_orphan_cleanup(struct super_block *sb,
|
|
|
ext4_msg(sb, KERN_INFO, "%d truncate%s cleaned up",
|
|
|
PLURAL(nr_truncates));
|
|
|
#ifdef CONFIG_QUOTA
|
|
|
- /* Turn off journaled quotas if they were enabled for orphan cleanup */
|
|
|
- for (i = 0; i < EXT4_MAXQUOTAS; i++) {
|
|
|
- if (EXT4_SB(sb)->s_qf_names[i] && sb_dqopt(sb)->files[i])
|
|
|
- dquot_quota_off(sb, i);
|
|
|
+ /* Turn off quotas if they were enabled for orphan cleanup */
|
|
|
+ if (quota_update) {
|
|
|
+ for (i = 0; i < EXT4_MAXQUOTAS; i++) {
|
|
|
+ if (sb_dqopt(sb)->files[i])
|
|
|
+ dquot_quota_off(sb, i);
|
|
|
+ }
|
|
|
}
|
|
|
#endif
|
|
|
sb->s_flags = s_flags; /* Restore MS_RDONLY status */
|
|
@@ -5512,6 +5533,9 @@ static int ext4_enable_quotas(struct super_block *sb)
|
|
|
DQUOT_USAGE_ENABLED |
|
|
|
(quota_mopt[type] ? DQUOT_LIMITS_ENABLED : 0));
|
|
|
if (err) {
|
|
|
+ for (type--; type >= 0; type--)
|
|
|
+ dquot_quota_off(sb, type);
|
|
|
+
|
|
|
ext4_warning(sb,
|
|
|
"Failed to enable quota tracking "
|
|
|
"(type=%d, err=%d). Please run "
|