Skip to content

Commit 0f5bde1

Browse files
jankaratytso
authored andcommitted
ext4: correctly restore system zone info when remount fails
When remounting filesystem fails late during remount handling and block_validity mount option is also changed during the remount, we fail to restore system zone information to a state matching the mount option. This is mostly harmless, just the block validity checking will not match the situation described by the mount option. Make sure these two are always consistent. Reported-by: Lukas Czerner <[email protected]> Reviewed-by: Lukas Czerner <[email protected]> Signed-off-by: Jan Kara <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Theodore Ts'o <[email protected]>
1 parent e7bfb5c commit 0f5bde1

File tree

2 files changed

+21
-16
lines changed

2 files changed

+21
-16
lines changed

fs/ext4/block_validity.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -220,14 +220,6 @@ int ext4_setup_system_zone(struct super_block *sb)
220220
int flex_size = ext4_flex_bg_size(sbi);
221221
int ret;
222222

223-
if (!test_opt(sb, BLOCK_VALIDITY)) {
224-
if (sbi->system_blks)
225-
ext4_release_system_zone(sb);
226-
return 0;
227-
}
228-
if (sbi->system_blks)
229-
return 0;
230-
231223
system_blks = kzalloc(sizeof(*system_blks), GFP_KERNEL);
232224
if (!system_blks)
233225
return -ENOMEM;

fs/ext4/super.c

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4727,11 +4727,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
47274727

47284728
ext4_set_resv_clusters(sb);
47294729

4730-
err = ext4_setup_system_zone(sb);
4731-
if (err) {
4732-
ext4_msg(sb, KERN_ERR, "failed to initialize system "
4733-
"zone (%d)", err);
4734-
goto failed_mount4a;
4730+
if (test_opt(sb, BLOCK_VALIDITY)) {
4731+
err = ext4_setup_system_zone(sb);
4732+
if (err) {
4733+
ext4_msg(sb, KERN_ERR, "failed to initialize system "
4734+
"zone (%d)", err);
4735+
goto failed_mount4a;
4736+
}
47354737
}
47364738

47374739
ext4_ext_init(sb);
@@ -5747,9 +5749,16 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
57475749
ext4_register_li_request(sb, first_not_zeroed);
57485750
}
57495751

5750-
err = ext4_setup_system_zone(sb);
5751-
if (err)
5752-
goto restore_opts;
5752+
/*
5753+
* Handle creation of system zone data early because it can fail.
5754+
* Releasing of existing data is done when we are sure remount will
5755+
* succeed.
5756+
*/
5757+
if (test_opt(sb, BLOCK_VALIDITY) && !sbi->system_blks) {
5758+
err = ext4_setup_system_zone(sb);
5759+
if (err)
5760+
goto restore_opts;
5761+
}
57535762

57545763
if (sbi->s_journal == NULL && !(old_sb_flags & SB_RDONLY)) {
57555764
err = ext4_commit_super(sb, 1);
@@ -5771,6 +5780,8 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
57715780
}
57725781
}
57735782
#endif
5783+
if (!test_opt(sb, BLOCK_VALIDITY) && sbi->system_blks)
5784+
ext4_release_system_zone(sb);
57745785

57755786
/*
57765787
* Some options can be enabled by ext4 and/or by VFS mount flag
@@ -5792,6 +5803,8 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
57925803
sbi->s_commit_interval = old_opts.s_commit_interval;
57935804
sbi->s_min_batch_time = old_opts.s_min_batch_time;
57945805
sbi->s_max_batch_time = old_opts.s_max_batch_time;
5806+
if (!test_opt(sb, BLOCK_VALIDITY) && sbi->system_blks)
5807+
ext4_release_system_zone(sb);
57955808
#ifdef CONFIG_QUOTA
57965809
sbi->s_jquota_fmt = old_opts.s_jquota_fmt;
57975810
for (i = 0; i < EXT4_MAXQUOTAS; i++) {

0 commit comments

Comments
 (0)