Unlike PAGE_SIZE == sectorsize case, read in subpage btrfs are always merged if the range is in the same page:
E.g: For regular sectorsize case, if we want to read range [0, 16K) of a file, the bio will look like: 0 4K 8K 12K 16K | bvec 1| bvec 2| bvec 3| bvec 4| But for subpage case, above 16K can be merged into one bvec: 0 4K 8K 12K 16K | bvec 1 | This means our bvec is no longer 1:1 mapped to btrfs sector. This makes repair much harder to do, if we want to do sector perfect repair. For now, just skip validation for subpage read repair, this means: - We will submit extra range to repair Even if we only have one sector error for above read, we will still submit full 16K to over-write the bad copy - Less chance to get good copy Now the repair granularity is much lower, we need a copy with all sectors correct to be able to submit a repair. Sector perfect repair needs more modification, but for now the new behavior should be good enough for us to test the basis of subpage support. Signed-off-by: Qu Wenruo <w...@suse.com> --- fs/btrfs/extent_io.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 152aface4eeb..81931c02c0e4 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -2651,6 +2651,19 @@ static bool btrfs_io_needs_validation(struct inode *inode, struct bio *bio) if (bio->bi_status == BLK_STS_OK) return false; + /* + * For subpage case, read bio are always submitted as multiple-sector + * bio if the range is in the same page. + * For now, let's just skip the validation, and do page sized repair. + * + * This reduce the granularity for repair, meaning if we have two + * copies with different csum mismatch at different location, we're + * unable to repair in subpage case. + * + * TODO: Make validation code to be fully subpage compatible + */ + if (blocksize < PAGE_SIZE) + return false; /* * We need to validate each sector individually if the failed I/O was * for multiple sectors. -- 2.31.1