Skip to content

Commit

Permalink
btrfs: scrub: fix incorrectly reported logical/physical address
Browse files Browse the repository at this point in the history
[BUG]
Scrub is not reporting the correct logical/physical address, it can be
verified by the following script:

 # mkfs.btrfs -f $dev1
 # mount $dev1 $mnt
 # xfs_io -f -c "pwrite -S 0xaa 0 128k" $mnt/file1
 # umount $mnt
 # xfs_io -f -c "pwrite -S 0xff 13647872 4k" $dev1
 # mount $dev1 $mnt
 # btrfs scrub start -fB $mnt
 # umount $mnt

Note above 13647872 is the physical address for logical 13631488 + 4K.

Scrub would report the following error:

 BTRFS error (device dm-2): unable to fixup (regular) error at logical 13631488 on dev /dev/mapper/test-scratch1 physical 13631488
 BTRFS warning (device dm-2): checksum error at logical 13631488 on dev /dev/mapper/test-scratch1, physical 13631488, root 5, inode 257, offset 0, length 4096, links 1 (path: file1)

On the other hand, "btrfs check --check-data-csum" is reporting the
correct logical/physical address:

 Checking filesystem on /dev/test/scratch1
 UUID: db2eb621-b09d-4f24-8199-da17dc7b3201
 [5/7] checking csums against data
 mirror 1 bytenr 13647872 csum 0x13fec125 expected csum 0x656bd64e
 ERROR: errors found in csum tree

[CAUSE]
In the function scrub_stripe_report_errors(), we always use the
stripe->logical and its physical address to print the error message, not
taking the sector number into consideration at all.

[FIX]
Fix the error reporting function by calculating logical/physical with
the sector number.

Now the scrub report is correct:

 BTRFS error (device dm-2): unable to fixup (regular) error at logical 13647872 on dev /dev/mapper/test-scratch1 physical 13647872
 BTRFS warning (device dm-2): checksum error at logical 13647872 on dev /dev/mapper/test-scratch1, physical 13647872, root 5, inode 257, offset 16384, length 4096, links 1 (path: file1)

Fixes: 0096580 ("btrfs: scrub: introduce error reporting functionality for scrub_stripe")
CC: stable@vger.kernel.org torvalds#6.4+
Reviewed-by: Anand Jain <anand.jain@oracle.com>
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
  • Loading branch information
adam900710 authored and kdave committed Oct 15, 2024
1 parent 69c77ce commit ee4d9bb
Showing 1 changed file with 13 additions and 9 deletions.
22 changes: 13 additions & 9 deletions fs/btrfs/scrub.c
Original file line number Diff line number Diff line change
Expand Up @@ -870,7 +870,7 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
DEFAULT_RATELIMIT_BURST);
struct btrfs_fs_info *fs_info = sctx->fs_info;
struct btrfs_device *dev = NULL;
u64 physical = 0;
u64 stripe_physical = stripe->physical;
int nr_data_sectors = 0;
int nr_meta_sectors = 0;
int nr_nodatacsum_sectors = 0;
Expand Down Expand Up @@ -903,13 +903,17 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
*/
if (ret < 0)
goto skip;
physical = bioc->stripes[stripe_index].physical;
stripe_physical = bioc->stripes[stripe_index].physical;
dev = bioc->stripes[stripe_index].dev;
btrfs_put_bioc(bioc);
}

skip:
for_each_set_bit(sector_nr, &stripe->extent_sector_bitmap, stripe->nr_sectors) {
const u64 logical = stripe->logical +
(sector_nr << fs_info->sectorsize_bits);
const u64 physical = stripe_physical +
(sector_nr << fs_info->sectorsize_bits);
bool repaired = false;

if (stripe->sectors[sector_nr].is_metadata) {
Expand Down Expand Up @@ -938,12 +942,12 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
if (dev) {
btrfs_err_rl_in_rcu(fs_info,
"fixed up error at logical %llu on dev %s physical %llu",
stripe->logical, btrfs_dev_name(dev),
logical, btrfs_dev_name(dev),
physical);
} else {
btrfs_err_rl_in_rcu(fs_info,
"fixed up error at logical %llu on mirror %u",
stripe->logical, stripe->mirror_num);
logical, stripe->mirror_num);
}
continue;
}
Expand All @@ -952,26 +956,26 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
if (dev) {
btrfs_err_rl_in_rcu(fs_info,
"unable to fixup (regular) error at logical %llu on dev %s physical %llu",
stripe->logical, btrfs_dev_name(dev),
logical, btrfs_dev_name(dev),
physical);
} else {
btrfs_err_rl_in_rcu(fs_info,
"unable to fixup (regular) error at logical %llu on mirror %u",
stripe->logical, stripe->mirror_num);
logical, stripe->mirror_num);
}

if (test_bit(sector_nr, &stripe->io_error_bitmap))
if (__ratelimit(&rs) && dev)
scrub_print_common_warning("i/o error", dev, false,
stripe->logical, physical);
logical, physical);
if (test_bit(sector_nr, &stripe->csum_error_bitmap))
if (__ratelimit(&rs) && dev)
scrub_print_common_warning("checksum error", dev, false,
stripe->logical, physical);
logical, physical);
if (test_bit(sector_nr, &stripe->meta_error_bitmap))
if (__ratelimit(&rs) && dev)
scrub_print_common_warning("header error", dev, false,
stripe->logical, physical);
logical, physical);
}

spin_lock(&sctx->stat_lock);
Expand Down

0 comments on commit ee4d9bb

Please sign in to comment.