Message ID | 20201127113405.26867-9-jack@suse.cz |
---|---|
State | Superseded |
Headers | show |
Series | ext4: Various fixes of ext4 handling of fs errors | expand |
On Fri, Nov 27, 2020 at 3:38 AM Jan Kara <jack@suse.cz> wrote: > > save_error_info() is always called together with ext4_handle_error(). > Combine them into a single call and move unconditional bits out of > save_error_info() into ext4_handle_error(). > > Signed-off-by: Jan Kara <jack@suse.cz> > --- > fs/ext4/super.c | 31 +++++++++++++++---------------- > 1 file changed, 15 insertions(+), 16 deletions(-) > > diff --git a/fs/ext4/super.c b/fs/ext4/super.c > index 2d7dc0908cdd..73a09b73fc11 100644 > --- a/fs/ext4/super.c > +++ b/fs/ext4/super.c > @@ -592,9 +592,6 @@ static void __save_error_info(struct super_block *sb, int error, > { > struct ext4_sb_info *sbi = EXT4_SB(sb); > > - EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; > - if (bdev_read_only(sb->s_bdev)) > - return; > /* We default to EFSCORRUPTED error... */ > if (error == 0) > error = EFSCORRUPTED; > @@ -647,13 +644,19 @@ static void save_error_info(struct super_block *sb, int error, > * used to deal with unrecoverable failures such as journal IO errors or ENOMEM > * at a critical moment in log management. > */ > -static void ext4_handle_error(struct super_block *sb, bool force_ro) > +static void ext4_handle_error(struct super_block *sb, bool force_ro, int error, > + __u32 ino, __u64 block, > + const char *func, unsigned int line) > { > journal_t *journal = EXT4_SB(sb)->s_journal; > > + EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; > if (test_opt(sb, WARN_ON_ERROR)) > WARN_ON_ONCE(1); > > + if (!bdev_read_only(sb->s_bdev)) > + save_error_info(sb, error, ino, block, func, line); > + > if (sb_rdonly(sb) || (!force_ro && test_opt(sb, ERRORS_CONT))) > return; > > @@ -710,8 +713,7 @@ void __ext4_error(struct super_block *sb, const char *function, > sb->s_id, function, line, current->comm, &vaf); > va_end(args); > } > - save_error_info(sb, error, 0, block, function, line); > - ext4_handle_error(sb, force_ro); > + ext4_handle_error(sb, force_ro, error, 0, block, function, line); > } > > void __ext4_error_inode(struct inode *inode, const char *function, > @@ -741,9 +743,8 @@ void __ext4_error_inode(struct inode *inode, const char *function, > current->comm, &vaf); > va_end(args); > } > - save_error_info(inode->i_sb, error, inode->i_ino, block, > - function, line); > - ext4_handle_error(inode->i_sb, false); > + ext4_handle_error(inode->i_sb, false, error, inode->i_ino, block, > + function, line); > } > > void __ext4_error_file(struct file *file, const char *function, > @@ -780,9 +781,8 @@ void __ext4_error_file(struct file *file, const char *function, > current->comm, path, &vaf); > va_end(args); > } > - save_error_info(inode->i_sb, EFSCORRUPTED, inode->i_ino, block, > - function, line); > - ext4_handle_error(inode->i_sb, false); > + ext4_handle_error(inode->i_sb, false, EFSCORRUPTED, inode->i_ino, block, > + function, line); > } > > const char *ext4_decode_error(struct super_block *sb, int errno, > @@ -849,8 +849,7 @@ void __ext4_std_error(struct super_block *sb, const char *function, > sb->s_id, function, line, errstr); > } > > - save_error_info(sb, -errno, 0, 0, function, line); > - ext4_handle_error(sb, false); > + ext4_handle_error(sb, false, -errno, 0, 0, function, line); > } > > void __ext4_msg(struct super_block *sb, > @@ -944,13 +943,13 @@ __acquires(bitlock) > if (test_opt(sb, ERRORS_CONT)) { > if (test_opt(sb, WARN_ON_ERROR)) > WARN_ON_ONCE(1); > + EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; Since you moved the bdev_read_only() check from __save_error_info to ext4_handle_error(), should we add that check here? - Harshad > __save_error_info(sb, EFSCORRUPTED, ino, block, function, line); > schedule_work(&EXT4_SB(sb)->s_error_work); > return; > } > ext4_unlock_group(sb, grp); > - save_error_info(sb, EFSCORRUPTED, ino, block, function, line); > - ext4_handle_error(sb, false); > + ext4_handle_error(sb, false, EFSCORRUPTED, ino, block, function, line); > /* > * We only get here in the ERRORS_RO case; relocking the group > * may be dangerous, but nothing bad will happen since the > -- > 2.16.4 >
On Mon 14-12-20 11:23:04, harshad shirwadkar wrote: > On Fri, Nov 27, 2020 at 3:38 AM Jan Kara <jack@suse.cz> wrote: > > > > save_error_info() is always called together with ext4_handle_error(). > > Combine them into a single call and move unconditional bits out of > > save_error_info() into ext4_handle_error(). > > > > Signed-off-by: Jan Kara <jack@suse.cz> > > --- > > fs/ext4/super.c | 31 +++++++++++++++---------------- > > 1 file changed, 15 insertions(+), 16 deletions(-) > > > > diff --git a/fs/ext4/super.c b/fs/ext4/super.c > > index 2d7dc0908cdd..73a09b73fc11 100644 > > --- a/fs/ext4/super.c > > +++ b/fs/ext4/super.c > > @@ -592,9 +592,6 @@ static void __save_error_info(struct super_block *sb, int error, > > { > > struct ext4_sb_info *sbi = EXT4_SB(sb); > > > > - EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; > > - if (bdev_read_only(sb->s_bdev)) > > - return; > > /* We default to EFSCORRUPTED error... */ > > if (error == 0) > > error = EFSCORRUPTED; ... > > @@ -944,13 +943,13 @@ __acquires(bitlock) > > if (test_opt(sb, ERRORS_CONT)) { > > if (test_opt(sb, WARN_ON_ERROR)) > > WARN_ON_ONCE(1); > > + EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; > Since you moved the bdev_read_only() check from __save_error_info to > ext4_handle_error(), should we add that check here? Thanks for the review! Now that I'm looking at it, you're probably right it would be safer. That being said I don't think it really matters: a) Because I don't think this function can get called on read-only bdev b) Because functions processing the work item will find out the sb is read-only and won't do anything. But it's really wasted work. I can see Ted didn't merge this patch yet. So I'll resend the series from this patch because after fixing this it required a bit of rebasing. Also I have two more additional fixes in the series based on Andreas' feedback. Thanks again for looking into the series! Honza
On Wed 16-12-20 11:11:47, Jan Kara wrote: > On Mon 14-12-20 11:23:04, harshad shirwadkar wrote: > > On Fri, Nov 27, 2020 at 3:38 AM Jan Kara <jack@suse.cz> wrote: > > > > > > save_error_info() is always called together with ext4_handle_error(). > > > Combine them into a single call and move unconditional bits out of > > > save_error_info() into ext4_handle_error(). > > > > > > Signed-off-by: Jan Kara <jack@suse.cz> > > > --- > > > fs/ext4/super.c | 31 +++++++++++++++---------------- > > > 1 file changed, 15 insertions(+), 16 deletions(-) > > > > > > diff --git a/fs/ext4/super.c b/fs/ext4/super.c > > > index 2d7dc0908cdd..73a09b73fc11 100644 > > > --- a/fs/ext4/super.c > > > +++ b/fs/ext4/super.c > > > @@ -592,9 +592,6 @@ static void __save_error_info(struct super_block *sb, int error, > > > { > > > struct ext4_sb_info *sbi = EXT4_SB(sb); > > > > > > - EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; > > > - if (bdev_read_only(sb->s_bdev)) > > > - return; > > > /* We default to EFSCORRUPTED error... */ > > > if (error == 0) > > > error = EFSCORRUPTED; > > ... > > > > @@ -944,13 +943,13 @@ __acquires(bitlock) > > > if (test_opt(sb, ERRORS_CONT)) { > > > if (test_opt(sb, WARN_ON_ERROR)) > > > WARN_ON_ONCE(1); > > > + EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; > > Since you moved the bdev_read_only() check from __save_error_info to > > ext4_handle_error(), should we add that check here? > > Thanks for the review! Now that I'm looking at it, you're probably right it > would be safer. That being said I don't think it really matters: > a) Because I don't think this function can get called on read-only bdev > b) Because functions processing the work item will find out the sb is > read-only and won't do anything. But it's really wasted work. > > I can see Ted didn't merge this patch yet. So I'll resend the series from > this patch because after fixing this it required a bit of rebasing. Also I > have two more additional fixes in the series based on Andreas' feedback. > > Thanks again for looking into the series! OK, fixed up patches sent: https://lore.kernel.org/linux-ext4/20201216101844.22917-1-jack@suse.cz Honza
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 2d7dc0908cdd..73a09b73fc11 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -592,9 +592,6 @@ static void __save_error_info(struct super_block *sb, int error, { struct ext4_sb_info *sbi = EXT4_SB(sb); - EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; - if (bdev_read_only(sb->s_bdev)) - return; /* We default to EFSCORRUPTED error... */ if (error == 0) error = EFSCORRUPTED; @@ -647,13 +644,19 @@ static void save_error_info(struct super_block *sb, int error, * used to deal with unrecoverable failures such as journal IO errors or ENOMEM * at a critical moment in log management. */ -static void ext4_handle_error(struct super_block *sb, bool force_ro) +static void ext4_handle_error(struct super_block *sb, bool force_ro, int error, + __u32 ino, __u64 block, + const char *func, unsigned int line) { journal_t *journal = EXT4_SB(sb)->s_journal; + EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; if (test_opt(sb, WARN_ON_ERROR)) WARN_ON_ONCE(1); + if (!bdev_read_only(sb->s_bdev)) + save_error_info(sb, error, ino, block, func, line); + if (sb_rdonly(sb) || (!force_ro && test_opt(sb, ERRORS_CONT))) return; @@ -710,8 +713,7 @@ void __ext4_error(struct super_block *sb, const char *function, sb->s_id, function, line, current->comm, &vaf); va_end(args); } - save_error_info(sb, error, 0, block, function, line); - ext4_handle_error(sb, force_ro); + ext4_handle_error(sb, force_ro, error, 0, block, function, line); } void __ext4_error_inode(struct inode *inode, const char *function, @@ -741,9 +743,8 @@ void __ext4_error_inode(struct inode *inode, const char *function, current->comm, &vaf); va_end(args); } - save_error_info(inode->i_sb, error, inode->i_ino, block, - function, line); - ext4_handle_error(inode->i_sb, false); + ext4_handle_error(inode->i_sb, false, error, inode->i_ino, block, + function, line); } void __ext4_error_file(struct file *file, const char *function, @@ -780,9 +781,8 @@ void __ext4_error_file(struct file *file, const char *function, current->comm, path, &vaf); va_end(args); } - save_error_info(inode->i_sb, EFSCORRUPTED, inode->i_ino, block, - function, line); - ext4_handle_error(inode->i_sb, false); + ext4_handle_error(inode->i_sb, false, EFSCORRUPTED, inode->i_ino, block, + function, line); } const char *ext4_decode_error(struct super_block *sb, int errno, @@ -849,8 +849,7 @@ void __ext4_std_error(struct super_block *sb, const char *function, sb->s_id, function, line, errstr); } - save_error_info(sb, -errno, 0, 0, function, line); - ext4_handle_error(sb, false); + ext4_handle_error(sb, false, -errno, 0, 0, function, line); } void __ext4_msg(struct super_block *sb, @@ -944,13 +943,13 @@ __acquires(bitlock) if (test_opt(sb, ERRORS_CONT)) { if (test_opt(sb, WARN_ON_ERROR)) WARN_ON_ONCE(1); + EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; __save_error_info(sb, EFSCORRUPTED, ino, block, function, line); schedule_work(&EXT4_SB(sb)->s_error_work); return; } ext4_unlock_group(sb, grp); - save_error_info(sb, EFSCORRUPTED, ino, block, function, line); - ext4_handle_error(sb, false); + ext4_handle_error(sb, false, EFSCORRUPTED, ino, block, function, line); /* * We only get here in the ERRORS_RO case; relocking the group * may be dangerous, but nothing bad will happen since the
save_error_info() is always called together with ext4_handle_error(). Combine them into a single call and move unconditional bits out of save_error_info() into ext4_handle_error(). Signed-off-by: Jan Kara <jack@suse.cz> --- fs/ext4/super.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-)