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 |
在 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);
Looks good,
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
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);
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(-)