diff mbox series

[08/12] ext4: Combine ext4_handle_error() and save_error_info()

Message ID 20201127113405.26867-9-jack@suse.cz
State Superseded
Headers show
Series ext4: Various fixes of ext4 handling of fs errors | expand

Commit Message

Jan Kara Nov. 27, 2020, 11:34 a.m. UTC
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(-)

Comments

harshad shirwadkar Dec. 14, 2020, 7:23 p.m. UTC | #1
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
>
Jan Kara Dec. 16, 2020, 10:11 a.m. UTC | #2
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
Jan Kara Dec. 16, 2020, 10:24 a.m. UTC | #3
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 mbox series

Patch

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