Commit 44a46d0
btrfs-progs: fix-data-checksum: fix an off-by-one error in the mirror bitmap
[BUG]
With both mirrors of a DUP data block corrupted, only the first one shows
up in the report:
# btrfs rescue fix-data-checksum dup.img
logical=84082688 corrtuped mirrors=1 affected files:
(subvolume 5)/file2
While both mirrors have a checksum mismatch, so the expected output is:
logical=84082688 corrtuped mirrors=1,2 affected files:
(subvolume 5)/file2
[CAUSE]
The error mirror bitmap uses bit 0 for mirror 1, as documented in struct
corrupted_block, and add_corrupted_block() does that conversion when it
allocates a new entry:
set_bit(mirror - 1, last->error_mirror_bitmap);
But when an entry for the same logical bytenr already exists, the mirror
number is used as the bit number directly:
set_bit(mirror, last->error_mirror_bitmap);
The first corrupted mirror of a block always goes through the allocation
path, so only the second and any following one are affected, and their bit
ends up one position too high.
For the last mirror this means bit @num_mirrors gets set, which is beyond
the range report_corrupted_blocks() walks, so the mirror is dropped from
the report. For the other mirrors the number reported is one larger than
the corrupted one, e.g. on a RAID1C3 block with mirrors 1 and 2 corrupted
the report claims mirrors 1 and 3, marking the only intact mirror as bad.
This is more than a cosmetic problem, as the report is what the user bases
the mirror choice on in the interactive mode. Picking a mirror that is
reported as intact but is in fact corrupted updates the checksum item to
match the corrupted data, making the corruption permanent.
[FIX]
Convert the mirror number to a bit number the same way the allocation path
does.
Fixes: 0e999c9 ("btrfs-progs: introduce "btrfs rescue fix-data-checksum"")
Signed-off-by: Sidong Yang <sidong.yang@furiosa.ai>1 parent 3dbed58 commit 44a46d0
1 file changed
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
85 | 85 | | |
86 | 86 | | |
87 | 87 | | |
88 | | - | |
| 88 | + | |
89 | 89 | | |
90 | 90 | | |
91 | 91 | | |
| |||
0 commit comments