From: Zygo Blaxell Date: Sat, 1 Aug 2026 22:31:19 +0000 (-0400) Subject: btrfs: raid56: only verify recovered sectors that have a checksum X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a13bca650db6cb61b19dade76dfeff31bb04bbcf;p=linux btrfs: raid56: only verify recovered sectors that have a checksum verify_one_sector() checks that the rbio has a csum_buf/csum_bitmap at all, but never tests the bitmap bit for the sector it is about to verify. A recovered sector that has no csum -- free space, or a sector whose ordered extent has not yet committed its csums, including the very sector a sub-stripe write is replacing -- is then compared against an all-zero csum_buf slot and fails with EIO. The visible symptom: sub-stripe writes to a degraded raid5/6 fail with EIO whenever the missing device's column in the target stripe is only partially covered by csums. The RMW read phase marks every sector of the missing device as an error, recover_sectors() rebuilds the column and verifies each rebuilt sector, and the first csum-less sector kills the write: BTRFS error (device loop3): dropping unwritten extent at root 5 ino 1061 offset [0,4095] disk bytenr 638771200 length 4096 with no underlying device error and no corruption counted anywhere. Writing new data into partially filled stripes is exactly what a degraded array must do to keep operating, so this makes a degraded raid56 filesystem effectively read-only for small writes, and each failure drops the unwritten extent (detectable data loss). fill_data_csums() only covers sectors that have csum items, and its sibling loop verify_bio_data_sectors() already skips sectors whose bitmap bit is clear. Do the same here. Fixes: 7a3150723061 ("btrfs: raid56: do data csum verification during RMW cycle") CC: stable@vger.kernel.org # 6.2+ Signed-off-by: Zygo Blaxell Assisted-by: Claude:claude-fable-5 --- diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c index fa2673f50e772..f84b88ec92d0d 100644 --- a/fs/btrfs/raid56.c +++ b/fs/btrfs/raid56.c @@ -1926,6 +1926,12 @@ static int verify_one_sector(struct btrfs_raid_bio *rbio, /* No way to verify P/Q as they are not covered by data csum. */ if (stripe_nr >= rbio->nr_data) return 0; + + /* No csum for this sector, nothing to verify against. */ + if (!test_bit(stripe_nr * rbio->stripe_nsectors + sector_nr, + rbio->csum_bitmap)) + return 0; + /* * If we're rebuilding a read, we have to use pages from the * bio list if possible.