]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
btrfs: scrub: skip initial RST lookup errors
authorJohannes Thumshirn <johannes.thumshirn@wdc.com>
Mon, 7 Oct 2024 11:52:48 +0000 (13:52 +0200)
committerDavid Sterba <dsterba@suse.com>
Mon, 11 Nov 2024 13:34:15 +0000 (14:34 +0100)
Performing the initial extent sector read on a RAID stripe-tree backed
filesystem with pre-allocated extents will cause the RAID stripe-tree
lookup code to return ENODATA, as pre-allocated extents do not have any
on-disk bytes and thus no RAID stripe-tree entries.

But the current scrub read code marks these extents as errors, because
the lookup fails.

If btrfs_map_block() returns -ENODATA, it means that the call to
btrfs_get_raid_extent_offset() returned -ENODATA, because there is no
entry for the corresponding range in the RAID stripe-tree. But as this
range is in the extent tree it means we've hit a pre-allocated extent. In
this case, don't mark the sector in the stripe's error bitmaps as faulty
and carry on to the next.

Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/scrub.c

index e141132b5c8dfa91187768a6937371484ce59a84..52e09f307462323d9ef84ab587c6d723be4fb65a 100644 (file)
@@ -1704,8 +1704,18 @@ static void scrub_submit_extent_sector_read(struct scrub_ctx *sctx,
                                              &stripe_len, &bioc, &io_stripe, &mirror);
                        btrfs_put_bioc(bioc);
                        if (err < 0) {
-                               set_bit(i, &stripe->io_error_bitmap);
-                               set_bit(i, &stripe->error_bitmap);
+                               if (err != -ENODATA) {
+                                       /*
+                                        * Earlier btrfs_get_raid_extent_offset()
+                                        * returned -ENODATA, which means there's
+                                        * no entry for the corresponding range
+                                        * in the stripe tree.  But if it's in
+                                        * the extent tree, then it's a preallocated
+                                        * extent and not an error.
+                                        */
+                                       set_bit(i, &stripe->io_error_bitmap);
+                                       set_bit(i, &stripe->error_bitmap);
+                               }
                                continue;
                        }