Skip to content

Commit 64e7b8c

Browse files
adam900710kdave
authored andcommitted
btrfs: raid56: prepare verify_bio_data_sectors() to support bs > ps cases
The function verify_bio_data_sectors() assume each fs block can be mapped by one page, blocking bs > ps support for raid56. Prepare it for bs > ps cases by: - Make get_bio_sector_nr() to consider bs > ps cases The function is utilized to calculate the sector number of a device bio submitted by btrfs raid56 layer. - Assemble a local paddrs[] for checksum calculation - Open code btrfs_check_block_csum() btrfs_check_block_csum() only supports fs blocks backed by large folios. But for raid56 we can have fs blocks backed by multiple non-contiguous pages, e.g. direct IO, encoded read/write/send. So instead of using btrfs_check_block_csum(), open code it to use btrfs_calculate_block_csum_pages(). Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent e0eadfc commit 64e7b8c

1 file changed

Lines changed: 18 additions & 8 deletions

File tree

fs/btrfs/raid56.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1620,9 +1620,9 @@ static int get_bio_sector_nr(struct btrfs_raid_bio *rbio, struct bio *bio)
16201620
int i;
16211621

16221622
for (i = 0; i < rbio->nr_sectors; i++) {
1623-
if (rbio->stripe_paddrs[i] == bvec_paddr)
1623+
if (rbio->stripe_paddrs[i * rbio->sector_nsteps] == bvec_paddr)
16241624
break;
1625-
if (rbio->bio_paddrs[i] == bvec_paddr)
1625+
if (rbio->bio_paddrs[i * rbio->sector_nsteps] == bvec_paddr)
16261626
break;
16271627
}
16281628
ASSERT(i < rbio->nr_sectors);
@@ -1655,7 +1655,11 @@ static void verify_bio_data_sectors(struct btrfs_raid_bio *rbio,
16551655
struct bio *bio)
16561656
{
16571657
struct btrfs_fs_info *fs_info = rbio->bioc->fs_info;
1658+
const u32 step = min(fs_info->sectorsize, PAGE_SIZE);
1659+
const u32 nr_steps = rbio->sector_nsteps;
16581660
int total_sector_nr = get_bio_sector_nr(rbio, bio);
1661+
u32 offset = 0;
1662+
phys_addr_t paddrs[BTRFS_MAX_BLOCKSIZE / PAGE_SIZE];
16591663
phys_addr_t paddr;
16601664

16611665
/* No data csum for the whole stripe, no need to verify. */
@@ -1666,18 +1670,24 @@ static void verify_bio_data_sectors(struct btrfs_raid_bio *rbio,
16661670
if (total_sector_nr >= rbio->nr_data * rbio->stripe_nsectors)
16671671
return;
16681672

1669-
btrfs_bio_for_each_block_all(paddr, bio, fs_info->sectorsize) {
1673+
btrfs_bio_for_each_block_all(paddr, bio, step) {
16701674
u8 csum_buf[BTRFS_CSUM_SIZE];
1671-
u8 *expected_csum = rbio->csum_buf + total_sector_nr * fs_info->csum_size;
1672-
int ret;
1675+
u8 *expected_csum;
1676+
1677+
paddrs[(offset / step) % nr_steps] = paddr;
1678+
offset += step;
1679+
1680+
/* Not yet covering the full fs block, continue to the next step. */
1681+
if (!IS_ALIGNED(offset, fs_info->sectorsize))
1682+
continue;
16731683

16741684
/* No csum for this sector, skip to the next sector. */
16751685
if (!test_bit(total_sector_nr, rbio->csum_bitmap))
16761686
continue;
16771687

1678-
ret = btrfs_check_block_csum(fs_info, paddr,
1679-
csum_buf, expected_csum);
1680-
if (ret < 0)
1688+
expected_csum = rbio->csum_buf + total_sector_nr * fs_info->csum_size;
1689+
btrfs_calculate_block_csum_pages(fs_info, paddrs, csum_buf);
1690+
if (unlikely(memcmp(csum_buf, expected_csum, fs_info->csum_size) != 0))
16811691
set_bit(total_sector_nr, rbio->error_bitmap);
16821692
total_sector_nr++;
16831693
}

0 commit comments

Comments
 (0)