summaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
authorYe Bin <yebin10@huawei.com>2023-03-07 14:17:02 +0800
committerTheodore Ts'o <tytso@mit.edu>2023-03-11 00:44:24 -0500
commiteee00237fa5ec8f704f7323b54e48cc34e2d9168 (patch)
tree445ade12ba330e6df21f9f05d41ce42c5aeebdf2 /fs/ext4
parent62913ae96de747091c4dacd06d158e7729c1a76d (diff)
downloadlinux-stable-eee00237fa5ec8f704f7323b54e48cc34e2d9168.tar.gz
linux-stable-eee00237fa5ec8f704f7323b54e48cc34e2d9168.tar.bz2
linux-stable-eee00237fa5ec8f704f7323b54e48cc34e2d9168.zip
ext4: commit super block if fs record error when journal record without error
Now, 'es->s_state' maybe covered by recover journal. And journal errno maybe not recorded in journal sb as IO error. ext4_update_super() only update error information when 'sbi->s_add_error_count' large than zero. Then 'EXT4_ERROR_FS' flag maybe lost. To solve above issue just recover 'es->s_state' error flag after journal replay like error info. Signed-off-by: Ye Bin <yebin10@huawei.com> Reviewed-by: Baokun Li <libaokun1@huawei.com> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://lore.kernel.org/r/20230307061703.245965-2-yebin@huaweicloud.com
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/super.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 46b7345d2b6a..effe5e5bab71 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -5959,6 +5959,7 @@ static int ext4_load_journal(struct super_block *sb,
err = jbd2_journal_wipe(journal, !really_read_only);
if (!err) {
char *save = kmalloc(EXT4_S_ERR_LEN, GFP_KERNEL);
+
if (save)
memcpy(save, ((char *) es) +
EXT4_S_ERR_START, EXT4_S_ERR_LEN);
@@ -5967,6 +5968,14 @@ static int ext4_load_journal(struct super_block *sb,
memcpy(((char *) es) + EXT4_S_ERR_START,
save, EXT4_S_ERR_LEN);
kfree(save);
+ es->s_state |= cpu_to_le16(EXT4_SB(sb)->s_mount_state &
+ EXT4_ERROR_FS);
+ /* Write out restored error information to the superblock */
+ if (!bdev_read_only(sb->s_bdev)) {
+ int err2;
+ err2 = ext4_commit_super(sb);
+ err = err ? : err2;
+ }
}
if (err) {