btrfs: scrub: run relocation repair when/only needed
commit 7192833c4e55b26e8f15ef58577867a1bc808036 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 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+ 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>
This commit is contained in:
parent
73aa8ea03a
commit
e498cc00e6
@ -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;
|
||||
|
||||
@ -1079,16 +1080,15 @@ out:
|
||||
* 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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user