Skip to content

Commit

Permalink
ext4: fix quota inconsistency during orphan cleanup for read-only mounts
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: zhangyi (F) <[email protected]>
Signed-off-by: Theodore Ts'o <[email protected]>
Reviewed-by: Jan Kara <[email protected]>
Cc: [email protected] # 3.18+
  • Loading branch information
zhangyi089 authored and tytso committed Aug 24, 2017
1 parent b0a5a95 commit 95f1fda
Showing 1 changed file with 31 additions and 7 deletions.
38 changes: 31 additions & 7 deletions fs/ext4/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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 "
Expand Down

0 comments on commit 95f1fda

Please sign in to comment.