]> www.infradead.org Git - users/hch/configfs.git/commitdiff
btrfs: scrub: run relocation repair when/only needed
authorNaohiro Aota <naohiro.aota@wdc.com>
Tue, 9 Apr 2024 14:18:52 +0000 (23:18 +0900)
committerDavid Sterba <dsterba@suse.com>
Wed, 17 Apr 2024 23:46:47 +0000 (01:46 +0200)
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>
fs/btrfs/scrub.c

index fa25004ab04e7b28d73dee024303c0dab4077db6..4b22cfe9a98cb0244288d0a961fc7f0e1c7daf4e 100644 (file)
@@ -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 @@ 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);