[PATCH v2] btrfs: raid56: fix an incorrect csum skip during rmw
Qu Wenruo <[email protected]>
| Newsgroups | org.kernel.vger.linux-btrfs |
|---|---|
| Message-ID | <757cd3e5422b7a880fc853a32037a031e189149c.1783846776.git.wqu@suse.com> |
Commit 7425a2894019 ("btrfs: introduce btrfs_bio_for_each_block_all()
helper") uses the new helper to replace the nested loop inside
verify_bio_data_sectors(), which simplifies the code.
However that also changed the behavior of "continue" when a block has no
data checksum.
Previously the "continue" will skip the old for() loop, which will also
increase @total_sector_nr.
Now the "continue" will skip the new btrfs_bio_for_each_block_all()
loop, which doesn't update @total_sector_nr.
This will affect RMW workflow, as RMW will load the data checksum, and
rely on that to recover any corruption before generating P/Q stripes.
Now if we hit a single block without checksum, we will skip verifying
the remaining data, and will use corrupted data to generate P/Q, killing
the old chance of recovery.
Thankfully this doesn't affect recover nor scrub.
For recover we never populate the data checksum and rely on the caller
to do the verification.
For scrub it's pretty much the same, the data stripe verification is
done by scrub before updating P/Q stripes.
Fix it by increasing @total_sector_nr before calling "continue".
Fixes: 7425a2894019 ("btrfs: introduce btrfs_bio_for_each_block_all() helper")
Signed-off-by: Qu Wenruo <[email protected]>
---
Changelog:
v2:
- Update the subject and commit message
This doesn't affect scrub nor rebuild, but RMW.
---
fs/btrfs/raid56.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c
index baaa18b3c958..885602ab6448 100644
--- a/fs/btrfs/raid56.c
+++ b/fs/btrfs/raid56.c
@@ -1679,8 +1679,10 @@ static void verify_bio_data_sectors(struct btrfs_raid_bio *rbio,
continue;
/* No csum for this sector, skip to the next sector. */
- if (!test_bit(total_sector_nr, rbio->csum_bitmap))
+ if (!test_bit(total_sector_nr, rbio->csum_bitmap)) {
+ total_sector_nr++;
continue;
+ }
expected_csum = rbio->csum_buf + total_sector_nr * fs_info->csum_size;
btrfs_calculate_block_csum_pages(fs_info, paddrs, csum_buf);
--
2.54.0