Skip to content

Commit c53f016

Browse files
zhangyi089gregkh
authored andcommitted
ext4: fix quota inconsistency during orphan cleanup for read-only mounts
commit 95f1fda47c9d8738f858c3861add7bf0a36a7c0b upstream. Quota does not get enabled for read-only mounts if filesystem has quota feature, so that quotas cannot updated during orphan cleanup, which will lead to quota inconsistency. This patch turn on quotas during orphan cleanup for this case, make sure quotas can be updated correctly. Reported-by: Jan Kara <jack@suse.cz> Signed-off-by: zhangyi (F) <yi.zhang@huawei.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu> Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent cd46241 commit c53f016

1 file changed

Lines changed: 31 additions & 7 deletions

File tree

fs/ext4/super.c

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2205,6 +2205,7 @@ static void ext4_orphan_cleanup(struct super_block *sb,
22052205
unsigned int s_flags = sb->s_flags;
22062206
int nr_orphans = 0, nr_truncates = 0;
22072207
#ifdef CONFIG_QUOTA
2208+
int quota_update = 0;
22082209
int i;
22092210
#endif
22102211
if (!es->s_last_orphan) {
@@ -2243,14 +2244,32 @@ static void ext4_orphan_cleanup(struct super_block *sb,
22432244
#ifdef CONFIG_QUOTA
22442245
/* Needed for iput() to work correctly and not trash data */
22452246
sb->s_flags |= MS_ACTIVE;
2246-
/* Turn on journaled quotas so that they are updated correctly */
2247+
2248+
/*
2249+
* Turn on quotas which were not enabled for read-only mounts if
2250+
* filesystem has quota feature, so that they are updated correctly.
2251+
*/
2252+
if (ext4_has_feature_quota(sb) && (s_flags & MS_RDONLY)) {
2253+
int ret = ext4_enable_quotas(sb);
2254+
2255+
if (!ret)
2256+
quota_update = 1;
2257+
else
2258+
ext4_msg(sb, KERN_ERR,
2259+
"Cannot turn on quotas: error %d", ret);
2260+
}
2261+
2262+
/* Turn on journaled quotas used for old sytle */
22472263
for (i = 0; i < EXT4_MAXQUOTAS; i++) {
22482264
if (EXT4_SB(sb)->s_qf_names[i]) {
22492265
int ret = ext4_quota_on_mount(sb, i);
2250-
if (ret < 0)
2266+
2267+
if (!ret)
2268+
quota_update = 1;
2269+
else
22512270
ext4_msg(sb, KERN_ERR,
22522271
"Cannot turn on journaled "
2253-
"quota: error %d", ret);
2272+
"quota: type %d: error %d", i, ret);
22542273
}
22552274
}
22562275
#endif
@@ -2309,10 +2328,12 @@ static void ext4_orphan_cleanup(struct super_block *sb,
23092328
ext4_msg(sb, KERN_INFO, "%d truncate%s cleaned up",
23102329
PLURAL(nr_truncates));
23112330
#ifdef CONFIG_QUOTA
2312-
/* Turn off journaled quotas if they were enabled for orphan cleanup */
2313-
for (i = 0; i < EXT4_MAXQUOTAS; i++) {
2314-
if (EXT4_SB(sb)->s_qf_names[i] && sb_dqopt(sb)->files[i])
2315-
dquot_quota_off(sb, i);
2331+
/* Turn off quotas if they were enabled for orphan cleanup */
2332+
if (quota_update) {
2333+
for (i = 0; i < EXT4_MAXQUOTAS; i++) {
2334+
if (sb_dqopt(sb)->files[i])
2335+
dquot_quota_off(sb, i);
2336+
}
23162337
}
23172338
#endif
23182339
sb->s_flags = s_flags; /* Restore MS_RDONLY status */
@@ -5120,6 +5141,9 @@ static int ext4_enable_quotas(struct super_block *sb)
51205141
err = ext4_quota_enable(sb, type, QFMT_VFS_V1,
51215142
DQUOT_USAGE_ENABLED);
51225143
if (err) {
5144+
for (type--; type >= 0; type--)
5145+
dquot_quota_off(sb, type);
5146+
51235147
ext4_warning(sb,
51245148
"Failed to enable quota tracking "
51255149
"(type=%d, err=%d). Please run "

0 commit comments

Comments
 (0)