diff mbox series

btrfs: scrub: run relocation repair when/only needed

Message ID 4f457478390d84f5ecdc3818e239cdb652654ea0.1712672186.git.naohiro.aota@wdc.com (mailing list archive)
State New, archived
Headers show
Series btrfs: scrub: run relocation repair when/only needed | expand

Commit Message

Naohiro Aota April 9, 2024, 2:18 p.m. UTC
When btrfs scrub finds an error, it reads mirrors to find correct data. If
all the errors are fixed, sctx->error_bitmap is cleared for the stripe
range. However, in the zoned mode, it runs relocation to repair scrub
errors when the bitmap is *not* empty, which is a flipped condition.

Also, it runs the relocation even if the scrub is read-only. This is missed
by a fix in commit 1f2030ff6e49 ("btrfs: scrub: respect the read-only flag
during repair").

The repair is only necessary when there is a repaired sector and should be
done on read-write scrub. So, tweak the condition for both regular and
zoned case.

Fixes: 54765392a1b9 ("btrfs: scrub: introduce helper to queue a stripe for scrub")
Fixes: 1f2030ff6e49 ("btrfs: scrub: respect the read-only flag during repair")
CC: stable@vger.kernel.org # 6.6+
Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
---
 fs/btrfs/scrub.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

Comments

Qu Wenruo April 9, 2024, 9:35 p.m. UTC | #1
在 2024/4/9 23:48, Naohiro Aota 写道:
> When btrfs scrub finds an error, it reads mirrors to find correct data. If
> all the errors are fixed, sctx->error_bitmap is cleared for the stripe
> range. However, in the zoned mode, it runs relocation to repair scrub
> errors when the bitmap is *not* empty, which is a flipped condition.
>
> Also, it runs the relocation even if the scrub is read-only. This is missed
> by a fix in commit 1f2030ff6e49 ("btrfs: scrub: respect the read-only flag
> during repair").
>
> The repair is only necessary when there is a repaired sector and should be
> done on read-write scrub. So, tweak the condition for both regular and
> zoned case.
>
> Fixes: 54765392a1b9 ("btrfs: scrub: introduce helper to queue a stripe for scrub")
> Fixes: 1f2030ff6e49 ("btrfs: scrub: respect the read-only flag during repair")
> CC: stable@vger.kernel.org # 6.6+
> Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>

Reviewed-by: Qu Wenruo <wqu@suse.com>

Thanks,
Qu
> ---
>   fs/btrfs/scrub.c | 18 +++++++++---------
>   1 file changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
> index fa25004ab04e..4b22cfe9a98c 100644
> --- a/fs/btrfs/scrub.c
> +++ b/fs/btrfs/scrub.c
> @@ -1012,6 +1012,7 @@ static void scrub_stripe_read_repair_worker(struct work_struct *work)
>   	struct btrfs_fs_info *fs_info = sctx->fs_info;
>   	int num_copies = btrfs_num_copies(fs_info, stripe->bg->start,
>   					  stripe->bg->length);
> +	unsigned long repaired;
>   	int mirror;
>   	int i;
>
> @@ -1078,16 +1079,15 @@ static void scrub_stripe_read_repair_worker(struct work_struct *work)
>   	 * Submit the repaired sectors.  For zoned case, we cannot do repair
>   	 * in-place, but queue the bg to be relocated.
>   	 */
> -	if (btrfs_is_zoned(fs_info)) {
> -		if (!bitmap_empty(&stripe->error_bitmap, stripe->nr_sectors))
> +	bitmap_andnot(&repaired, &stripe->init_error_bitmap, &stripe->error_bitmap,
> +		      stripe->nr_sectors);
> +	if (!sctx->readonly && !bitmap_empty(&repaired, stripe->nr_sectors)) {
> +		if (btrfs_is_zoned(fs_info)) {
>   			btrfs_repair_one_zone(fs_info, sctx->stripes[0].bg->start);
> -	} else if (!sctx->readonly) {
> -		unsigned long repaired;
> -
> -		bitmap_andnot(&repaired, &stripe->init_error_bitmap,
> -			      &stripe->error_bitmap, stripe->nr_sectors);
> -		scrub_write_sectors(sctx, stripe, repaired, false);
> -		wait_scrub_stripe_io(stripe);
> +		} else {
> +			scrub_write_sectors(sctx, stripe, repaired, false);
> +			wait_scrub_stripe_io(stripe);
> +		}
>   	}
>
>   	scrub_stripe_report_errors(sctx, stripe);
Johannes Thumshirn April 10, 2024, 7:47 a.m. UTC | #2
Looks good,
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
diff mbox series

Patch

diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index fa25004ab04e..4b22cfe9a98c 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -1012,6 +1012,7 @@  static void scrub_stripe_read_repair_worker(struct work_struct *work)
 	struct btrfs_fs_info *fs_info = sctx->fs_info;
 	int num_copies = btrfs_num_copies(fs_info, stripe->bg->start,
 					  stripe->bg->length);
+	unsigned long repaired;
 	int mirror;
 	int i;
 
@@ -1078,16 +1079,15 @@  static void scrub_stripe_read_repair_worker(struct work_struct *work)
 	 * Submit the repaired sectors.  For zoned case, we cannot do repair
 	 * in-place, but queue the bg to be relocated.
 	 */
-	if (btrfs_is_zoned(fs_info)) {
-		if (!bitmap_empty(&stripe->error_bitmap, stripe->nr_sectors))
+	bitmap_andnot(&repaired, &stripe->init_error_bitmap, &stripe->error_bitmap,
+		      stripe->nr_sectors);
+	if (!sctx->readonly && !bitmap_empty(&repaired, stripe->nr_sectors)) {
+		if (btrfs_is_zoned(fs_info)) {
 			btrfs_repair_one_zone(fs_info, sctx->stripes[0].bg->start);
-	} else if (!sctx->readonly) {
-		unsigned long repaired;
-
-		bitmap_andnot(&repaired, &stripe->init_error_bitmap,
-			      &stripe->error_bitmap, stripe->nr_sectors);
-		scrub_write_sectors(sctx, stripe, repaired, false);
-		wait_scrub_stripe_io(stripe);
+		} else {
+			scrub_write_sectors(sctx, stripe, repaired, false);
+			wait_scrub_stripe_io(stripe);
+		}
 	}
 
 	scrub_stripe_report_errors(sctx, stripe);