summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQu Wenruo <wqu@suse.com>2025-11-17 13:57:55 +1030
committerDavid Sterba <dsterba@suse.com>2025-11-25 01:47:31 +0100
commit05ddf35a5d3d8d58323d6353f2bad026e9838af8 (patch)
tree50b16322665f09d1ccad3cea4a691d821070845c
parent64e7b8c7c5873ad03e108d775fa1c0063a320070 (diff)
btrfs: raid56: prepare set_bio_pages_uptodate() to support bs > ps cases
The function set_bio_pages_uptodate() assume each fs block can be mapped by one page, blocking bs > ps support for raid56. Prepare it for bs > ps cases by: - Update find_stripe_sector_nr() to check only the first step paddr We don't need to check each paddr, as the bios are still aligned to fs block size, thus checking the first step is enough. - Use step size to iterate the bio This means we only need to find the sector number for the first step of each fs block, and skip the remaining part. Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--fs/btrfs/raid56.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c
index 7bc43f1861e6..2b6838380544 100644
--- a/fs/btrfs/raid56.c
+++ b/fs/btrfs/raid56.c
@@ -1588,7 +1588,7 @@ static void set_rbio_range_error(struct btrfs_raid_bio *rbio, struct bio *bio)
static int find_stripe_sector_nr(struct btrfs_raid_bio *rbio, phys_addr_t paddr)
{
for (int i = 0; i < rbio->nr_sectors; i++) {
- if (rbio->stripe_paddrs[i] == paddr)
+ if (rbio->stripe_paddrs[i * rbio->sector_nsteps] == paddr)
return i;
}
return -1;
@@ -1600,17 +1600,23 @@ static int find_stripe_sector_nr(struct btrfs_raid_bio *rbio, phys_addr_t paddr)
*/
static void set_bio_pages_uptodate(struct btrfs_raid_bio *rbio, struct bio *bio)
{
- const u32 blocksize = rbio->bioc->fs_info->sectorsize;
+ const u32 sectorsize = rbio->bioc->fs_info->sectorsize;
+ const u32 step = min(sectorsize, PAGE_SIZE);
+ u32 offset = 0;
phys_addr_t paddr;
ASSERT(!bio_flagged(bio, BIO_CLONED));
- btrfs_bio_for_each_block_all(paddr, bio, blocksize) {
- int sector_nr = find_stripe_sector_nr(rbio, paddr);
+ btrfs_bio_for_each_block_all(paddr, bio, step) {
+ /* Hitting the first step of a sector. */
+ if (IS_ALIGNED(offset, sectorsize)) {
+ int sector_nr = find_stripe_sector_nr(rbio, paddr);
- ASSERT(sector_nr >= 0);
- if (sector_nr >= 0)
- set_bit(sector_nr, rbio->stripe_uptodate_bitmap);
+ ASSERT(sector_nr >= 0);
+ if (sector_nr >= 0)
+ set_bit(sector_nr, rbio->stripe_uptodate_bitmap);
+ }
+ offset += step;
}
}