Skip to content

Commit

Permalink
btrfs: scrub: run relocation repair when/only needed
Browse files Browse the repository at this point in the history
commit 7192833 upstream.

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 was
missed by a fix in commit 1f2030f ("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: 5476539 ("btrfs: scrub: introduce helper to queue a stripe for scrub")
Fixes: 1f2030f ("btrfs: scrub: respect the read-only flag during repair")
CC: stable@vger.kernel.org # 6.6+
Reviewed-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
naota authored and gregkh committed May 2, 2024
1 parent 73aa8ea commit e498cc0
Showing 1 changed file with 9 additions and 9 deletions.
18 changes: 9 additions & 9 deletions fs/btrfs/scrub.c
Original file line number Diff line number Diff line change
Expand Up @@ -1013,6 +1013,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;

Expand Down Expand Up @@ -1079,16 +1080,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);
Expand Down

0 comments on commit e498cc0

Please sign in to comment.