Skip to content

Commit 53474a2

Browse files
adam900710kdave
authored andcommitted
btrfs: raid56: prepare steal_rbio() to support bs > ps cases
The function steal_rbio() assume each fs block can be mapped by one page, blocking bs > ps support for raid56. Prepare it for bs > ps cases by: - Introduce two helpers to calculate the sector number Previously we assume one page will contain at least one fs block, thus can use something like "sectors_per_page = PAGE_SIZE / sectorsize;", but with bs > ps support that above number will be 0. Instead introduce two helpers: * page_nr_to_sector_nr() Returns the sector number of the first sector covered by the page. * page_nr_to_num_sectors() Return how many sectors are covered by the page. And use the returned values for bitmap operations other than open-coded "PAGE_SIZE / sectorsize". Those helpers also have extra ASSERT()s to catch weird numbers. - Use above helpers The involved functions are: * steal_rbio_page() * is_data_stripe_page() * full_page_sectors_uptodate() Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 05ddf35 commit 53474a2

1 file changed

Lines changed: 41 additions & 10 deletions

File tree

fs/btrfs/raid56.c

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -300,18 +300,47 @@ static int rbio_bucket(struct btrfs_raid_bio *rbio)
300300
return hash_64(num >> 16, BTRFS_STRIPE_HASH_TABLE_BITS);
301301
}
302302

303+
/* Get the sector number of the first sector covered by @page_nr. */
304+
static u32 page_nr_to_sector_nr(struct btrfs_raid_bio *rbio, unsigned int page_nr)
305+
{
306+
u32 sector_nr;
307+
308+
ASSERT(page_nr < rbio->nr_pages);
309+
310+
sector_nr = (page_nr << PAGE_SHIFT) >> rbio->bioc->fs_info->sectorsize_bits;
311+
ASSERT(sector_nr < rbio->nr_sectors);
312+
return sector_nr;
313+
}
314+
315+
/*
316+
* Get the number of sectors covered by @page_nr.
317+
*
318+
* For bs > ps cases, the result will always be 1.
319+
* For bs <= ps cases, the result will be ps / bs.
320+
*/
321+
static u32 page_nr_to_num_sectors(struct btrfs_raid_bio *rbio, unsigned int page_nr)
322+
{
323+
struct btrfs_fs_info *fs_info = rbio->bioc->fs_info;
324+
u32 nr_sectors;
325+
326+
ASSERT(page_nr < rbio->nr_pages);
327+
328+
nr_sectors = round_up(PAGE_SIZE, fs_info->sectorsize) >> fs_info->sectorsize_bits;
329+
ASSERT(nr_sectors > 0);
330+
return nr_sectors;
331+
}
332+
303333
static __maybe_unused bool full_page_sectors_uptodate(struct btrfs_raid_bio *rbio,
304334
unsigned int page_nr)
305335
{
306-
const u32 sectorsize = rbio->bioc->fs_info->sectorsize;
307-
const u32 sectors_per_page = PAGE_SIZE / sectorsize;
336+
const u32 sector_nr = page_nr_to_sector_nr(rbio, page_nr);
337+
const u32 nr_bits = page_nr_to_num_sectors(rbio, page_nr);
308338
int i;
309339

310340
ASSERT(page_nr < rbio->nr_pages);
341+
ASSERT(sector_nr + nr_bits < rbio->nr_sectors);
311342

312-
for (i = sectors_per_page * page_nr;
313-
i < sectors_per_page * page_nr + sectors_per_page;
314-
i++) {
343+
for (i = sector_nr; i < sector_nr + nr_bits; i++) {
315344
if (!test_bit(i, rbio->stripe_uptodate_bitmap))
316345
return false;
317346
}
@@ -345,22 +374,24 @@ static void index_stripe_sectors(struct btrfs_raid_bio *rbio)
345374
static void steal_rbio_page(struct btrfs_raid_bio *src,
346375
struct btrfs_raid_bio *dest, int page_nr)
347376
{
348-
const u32 sectorsize = src->bioc->fs_info->sectorsize;
349-
const u32 sectors_per_page = PAGE_SIZE / sectorsize;
377+
const u32 sector_nr = page_nr_to_sector_nr(src, page_nr);
378+
const u32 nr_bits = page_nr_to_num_sectors(src, page_nr);
379+
380+
ASSERT(page_nr < src->nr_pages);
381+
ASSERT(sector_nr + nr_bits < src->nr_sectors);
350382

351383
if (dest->stripe_pages[page_nr])
352384
__free_page(dest->stripe_pages[page_nr]);
353385
dest->stripe_pages[page_nr] = src->stripe_pages[page_nr];
354386
src->stripe_pages[page_nr] = NULL;
355387

356388
/* Also update the stripe_uptodate_bitmap bits. */
357-
bitmap_set(dest->stripe_uptodate_bitmap, sectors_per_page * page_nr, sectors_per_page);
389+
bitmap_set(dest->stripe_uptodate_bitmap, sector_nr, nr_bits);
358390
}
359391

360392
static bool is_data_stripe_page(struct btrfs_raid_bio *rbio, int page_nr)
361393
{
362-
const int sector_nr = (page_nr << PAGE_SHIFT) >>
363-
rbio->bioc->fs_info->sectorsize_bits;
394+
const int sector_nr = page_nr_to_sector_nr(rbio, page_nr);
364395

365396
/*
366397
* We have ensured PAGE_SIZE is aligned with sectorsize, thus

0 commit comments

Comments
 (0)