Re: [PATCH v2] btrfs: scrub: report the failing sector's address, not the stripe base

Qu Wenruo <[email protected]>
Newsgroups org.kernel.vger.linux-btrfs
Message-ID <[email protected]>

在 2026/8/16 01:04, James C. Owens 写道:
> scrub_stripe_report_errors() iterates over the sectors of a stripe, but
> every message it emits passes stripe->logical, the address of the first
> sector of the 64KiB stripe, rather than the address of the sector being
> reported. The physical address is likewise computed once, before the
> loop, from stripe->logical.
> 
> This matters because scrub_print_common_warning() uses that logical
> address for the backref walk which produces the "root %llu inode %llu
> offset %llu ... (path: ...)" part of the message. As the address is
> always the stripe base, the reported root/inode/offset/path can identify
> a different file from the one whose sector actually failed.
> 
> A 64KiB stripe routinely spans several extents belonging to unrelated
> files. On the machine where this was found, the stripe at logical
> 0x17D9380000 holds four sectors of /usr/share/plasma/emoji/bg.dict, then
> a file inside a docker volume, then sectors referenced only by
> snapshots. Every error anywhere in that stripe is attributed to bg.dict.
> 
> The effect is visible statistically: across ten months and four kernel
> series that machine logged 81 distinct flagged logical addresses, and
> every one of them is exactly 64KiB aligned. Since BTRFS_STRIPE_LEN is
> 64KiB and stripe->logical is stripe aligned by construction, real
> failures distributed across sectors could not produce that.
> 
> Report the address of the sector actually being examined. Adding the
> sector offset to the physical address is valid because BTRFS_STRIPE_LEN
> is the unit contiguous on a single device for every profile, so a stripe
> never crosses a device boundary.
> 
> Fixes: 0096580713ff ("btrfs: scrub: introduce error reporting functionality for scrub_stripe")
> Signed-off-by: James C. Owens <[email protected]>
> Reviewed-by: Qu Wenruo <[email protected]>
> ---
> v2:
>   - Regenerate the patch with git format-patch. v1 was produced with plain
>     diff(1) and so lacked the diffstat, the "diff --git" header, the index
>     line and the function context in the hunk headers. Thanks Qu for catching
>     it; no code change.

Great that the mystery got solved!

The v1 version is already pushed to for-next with involved tags added.
So nothing to worry about.

Thanks,
Qu

>   - Add the Fixes: tag Qu supplied.
>   - Carry Qu's Reviewed-by.
> 
>   fs/btrfs/scrub.c | 24 ++++++++++++++----------
>   1 file changed, 14 insertions(+), 10 deletions(-)
> 
> diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
> index d2f7ac5b6e96..09b6003d3019 100644
> --- a/fs/btrfs/scrub.c
> +++ b/fs/btrfs/scrub.c
> @@ -1041,6 +1041,10 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
>   
>   skip:
>   	for_each_set_bit(sector_nr, &extent_bitmap, stripe->nr_sectors) {
> +		const u64 sector_logical = stripe->logical +
> +			((u64)sector_nr << fs_info->sectorsize_bits);
> +		const u64 sector_physical = physical +
> +			((u64)sector_nr << fs_info->sectorsize_bits);
>   		bool repaired = false;
>   
>   		if (scrub_bitmap_test_bit_is_metadata(stripe, sector_nr)) {
> @@ -1069,12 +1073,12 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
>   			if (dev) {
>   				btrfs_err_rl(fs_info,
>   		"scrub: fixed up error at logical %llu on dev %s physical %llu",
> -					    stripe->logical, btrfs_dev_name(dev),
> -					    physical);
> +					    sector_logical, btrfs_dev_name(dev),
> +					    sector_physical);
>   			} else {
>   				btrfs_err_rl(fs_info,
>   			   "scrub: fixed up error at logical %llu on mirror %u",
> -					    stripe->logical, stripe->mirror_num);
> +					    sector_logical, stripe->mirror_num);
>   			}
>   			continue;
>   		}
> @@ -1083,30 +1087,30 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
>   		if (dev) {
>   			btrfs_err_rl(fs_info,
>   "scrub: unable to fixup (regular) error at logical %llu on dev %s physical %llu",
> -					    stripe->logical, btrfs_dev_name(dev),
> -					    physical);
> +					    sector_logical, btrfs_dev_name(dev),
> +					    sector_physical);
>   		} else {
>   			btrfs_err_rl(fs_info,
>   	  "scrub: unable to fixup (regular) error at logical %llu on mirror %u",
> -					    stripe->logical, stripe->mirror_num);
> +					    sector_logical, stripe->mirror_num);
>   		}
>   
>   		if (scrub_bitmap_test_bit_io_error(stripe, sector_nr))
>   			if (__ratelimit(&rs) && dev)
>   				scrub_print_common_warning("i/o error", dev, false,
> -						     stripe->logical, physical);
> +						     sector_logical, sector_physical);
>   		if (scrub_bitmap_test_bit_csum_error(stripe, sector_nr))
>   			if (__ratelimit(&rs) && dev)
>   				scrub_print_common_warning("checksum error", dev, false,
> -						     stripe->logical, physical);
> +						     sector_logical, sector_physical);
>   		if (scrub_bitmap_test_bit_meta_error(stripe, sector_nr))
>   			if (__ratelimit(&rs) && dev)
>   				scrub_print_common_warning("header error", dev, false,
> -						     stripe->logical, physical);
> +						     sector_logical, sector_physical);
>   		if (scrub_bitmap_test_bit_meta_gen_error(stripe, sector_nr))
>   			if (__ratelimit(&rs) && dev)
>   				scrub_print_common_warning("generation error", dev, false,
> -						     stripe->logical, physical);
> +						     sector_logical, sector_physical);
>   	}
>   
>   	/* Update the device stats. */
> 
> base-commit: 15ef2f78c49d20d53ec7c0f1c9b40b02e089f2d6
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.