On Tue 14-02-23 10:29:04, Ye Bin wrote: > From: Ye Bin <yebin10@xxxxxxxxxx> > > 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 commit error information after recover journal. > > Signed-off-by: Ye Bin <yebin10@xxxxxxxxxx> > --- > fs/ext4/super.c | 12 ++++++++++++ > 1 file changed, 12 insertions(+) > > diff --git a/fs/ext4/super.c b/fs/ext4/super.c > index dc3907dff13a..b94754ba8556 100644 > --- a/fs/ext4/super.c > +++ b/fs/ext4/super.c > @@ -5932,6 +5932,18 @@ static int ext4_load_journal(struct super_block *sb, > goto err_out; > } > > + if (unlikely(es->s_error_count && !jbd2_journal_errno(journal) && > + !(le16_to_cpu(es->s_state) & EXT4_ERROR_FS))) { > + EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; > + es->s_state |= cpu_to_le16(EXT4_ERROR_FS); > + err = ext4_commit_super(sb); > + if (err) { > + ext4_msg(sb, KERN_ERR, > + "Failed to commit error information, please repair fs force!"); > + goto err_out; > + } > + } > + Hum, I'm not sure I follow here. If journal replay has overwritten the superblock (and thus the stored error info), then I'd expect es->s_error_count got overwritten (possibly to 0) as well. And this is actually relatively realistic scenario with errors=remount-ro behavior when the first fs error happens. What I intended in my original suggestion was to save es->s_error_count, es->s_state & EXT4_ERROR_FS, es->s_first_error_*, es->s_last_error_* before doing journal replay in ext4_load_journal() and then after journal replay merge this info back to the superblock - if EXT4_ERROR_FS was set, set it now as well, take max of old and new s_error_count, set s_first_error_* if it is now unset, set s_last_error_* if stored timestamp is newer than current timestamp. Or am I overengineering it now? :) Honza -- Jan Kara <jack@xxxxxxxx> SUSE Labs, CR