@@ -66,10 +66,10 @@ static void btrfs_dump_rbio(const struct btrfs_fs_info *fs_info,
6666
6767 dump_bioc (fs_info , rbio -> bioc );
6868 btrfs_crit (fs_info ,
69- "rbio flags=0x%lx nr_sectors=%u nr_data=%u real_stripes=%u stripe_nsectors=%u scrubp=%u dbitmap=0x%lx" ,
69+ "rbio flags=0x%lx nr_sectors=%u nr_data=%u real_stripes=%u stripe_nsectors=%u sector_nsteps=%u scrubp=%u dbitmap=0x%lx" ,
7070 rbio -> flags , rbio -> nr_sectors , rbio -> nr_data ,
7171 rbio -> real_stripes , rbio -> stripe_nsectors ,
72- rbio -> scrubp , rbio -> dbitmap );
72+ rbio -> sector_nsteps , rbio -> scrubp , rbio -> dbitmap );
7373}
7474
7575#define ASSERT_RBIO (expr , rbio ) \
@@ -229,15 +229,20 @@ int btrfs_alloc_stripe_hash_table(struct btrfs_fs_info *info)
229229
230230static void memcpy_from_bio_to_stripe (struct btrfs_raid_bio * rbio , unsigned int sector_nr )
231231{
232- phys_addr_t dst = rbio -> stripe_paddrs [sector_nr ];
233- phys_addr_t src = rbio -> bio_paddrs [sector_nr ];
232+ const u32 step = min (rbio -> bioc -> fs_info -> sectorsize , PAGE_SIZE );
234233
235- ASSERT (dst != INVALID_PADDR );
236- ASSERT (src != INVALID_PADDR );
234+ ASSERT (sector_nr < rbio -> nr_sectors );
235+ for (int i = 0 ; i < rbio -> sector_nsteps ; i ++ ) {
236+ unsigned int index = sector_nr * rbio -> sector_nsteps + i ;
237+ phys_addr_t dst = rbio -> stripe_paddrs [index ];
238+ phys_addr_t src = rbio -> bio_paddrs [index ];
237239
238- memcpy_page (phys_to_page (dst ), offset_in_page (dst ),
239- phys_to_page (src ), offset_in_page (src ),
240- rbio -> bioc -> fs_info -> sectorsize );
240+ ASSERT (dst != INVALID_PADDR );
241+ ASSERT (src != INVALID_PADDR );
242+
243+ memcpy_page (phys_to_page (dst ), offset_in_page (dst ),
244+ phys_to_page (src ), offset_in_page (src ), step );
245+ }
241246}
242247
243248/*
@@ -260,7 +265,7 @@ static void cache_rbio_pages(struct btrfs_raid_bio *rbio)
260265
261266 for (i = 0 ; i < rbio -> nr_sectors ; i ++ ) {
262267 /* Some range not covered by bio (partial write), skip it */
263- if (rbio -> bio_paddrs [i ] == INVALID_PADDR ) {
268+ if (rbio -> bio_paddrs [i * rbio -> sector_nsteps ] == INVALID_PADDR ) {
264269 /*
265270 * Even if the sector is not covered by bio, if it is
266271 * a data sector it should still be uptodate as it is
@@ -320,11 +325,12 @@ static __maybe_unused bool full_page_sectors_uptodate(struct btrfs_raid_bio *rbi
320325 */
321326static void index_stripe_sectors (struct btrfs_raid_bio * rbio )
322327{
323- const u32 sectorsize = rbio -> bioc -> fs_info -> sectorsize ;
328+ const u32 step = min ( rbio -> bioc -> fs_info -> sectorsize , PAGE_SIZE ) ;
324329 u32 offset ;
325330 int i ;
326331
327- for (i = 0 , offset = 0 ; i < rbio -> nr_sectors ; i ++ , offset += sectorsize ) {
332+ for (i = 0 , offset = 0 ; i < rbio -> nr_sectors * rbio -> sector_nsteps ;
333+ i ++ , offset += step ) {
328334 int page_index = offset >> PAGE_SHIFT ;
329335
330336 ASSERT (page_index < rbio -> nr_pages );
@@ -668,21 +674,41 @@ static int rbio_can_merge(struct btrfs_raid_bio *last,
668674 return 1 ;
669675}
670676
671- static unsigned int rbio_stripe_sector_index (const struct btrfs_raid_bio * rbio ,
672- unsigned int stripe_nr ,
673- unsigned int sector_nr )
677+ /* Return the sector index for @stripe_nr and @sector_nr. */
678+ static unsigned int rbio_sector_index (const struct btrfs_raid_bio * rbio ,
679+ unsigned int stripe_nr ,
680+ unsigned int sector_nr )
674681{
682+ unsigned int ret ;
683+
675684 ASSERT_RBIO_STRIPE (stripe_nr < rbio -> real_stripes , rbio , stripe_nr );
676685 ASSERT_RBIO_SECTOR (sector_nr < rbio -> stripe_nsectors , rbio , sector_nr );
677686
678- return stripe_nr * rbio -> stripe_nsectors + sector_nr ;
687+ ret = stripe_nr * rbio -> stripe_nsectors + sector_nr ;
688+ ASSERT (ret < rbio -> nr_sectors );
689+ return ret ;
690+ }
691+
692+ /* Return the paddr array index for @stripe_nr, @sector_nr and @step_nr. */
693+ static unsigned int rbio_paddr_index (const struct btrfs_raid_bio * rbio ,
694+ unsigned int stripe_nr ,
695+ unsigned int sector_nr ,
696+ unsigned int step_nr )
697+ {
698+ unsigned int ret ;
699+
700+ ASSERT_RBIO_SECTOR (step_nr < rbio -> sector_nsteps , rbio , step_nr );
701+
702+ ret = rbio_sector_index (rbio , stripe_nr , sector_nr ) * rbio -> sector_nsteps + step_nr ;
703+ ASSERT (ret < rbio -> nr_sectors * rbio -> sector_nsteps );
704+ return ret ;
679705}
680706
681707/* Return a paddr from rbio->stripe_sectors, not from the bio list */
682708static phys_addr_t rbio_stripe_paddr (const struct btrfs_raid_bio * rbio ,
683709 unsigned int stripe_nr , unsigned int sector_nr )
684710{
685- return rbio -> stripe_paddrs [rbio_stripe_sector_index (rbio , stripe_nr , sector_nr )];
711+ return rbio -> stripe_paddrs [rbio_paddr_index (rbio , stripe_nr , sector_nr , 0 )];
686712}
687713
688714/* Grab a paddr inside P stripe */
@@ -985,6 +1011,8 @@ static struct btrfs_raid_bio *alloc_rbio(struct btrfs_fs_info *fs_info,
9851011 const unsigned int stripe_nsectors =
9861012 BTRFS_STRIPE_LEN >> fs_info -> sectorsize_bits ;
9871013 const unsigned int num_sectors = stripe_nsectors * real_stripes ;
1014+ const unsigned int step = min (fs_info -> sectorsize , PAGE_SIZE );
1015+ const unsigned int sector_nsteps = fs_info -> sectorsize / step ;
9881016 struct btrfs_raid_bio * rbio ;
9891017
9901018 /* PAGE_SIZE must also be aligned to sectorsize for subpage support */
@@ -1007,8 +1035,8 @@ static struct btrfs_raid_bio *alloc_rbio(struct btrfs_fs_info *fs_info,
10071035 return ERR_PTR (- ENOMEM );
10081036 rbio -> stripe_pages = kcalloc (num_pages , sizeof (struct page * ),
10091037 GFP_NOFS );
1010- rbio -> bio_paddrs = kcalloc (num_sectors , sizeof (phys_addr_t ), GFP_NOFS );
1011- rbio -> stripe_paddrs = kcalloc (num_sectors , sizeof (phys_addr_t ), GFP_NOFS );
1038+ rbio -> bio_paddrs = kcalloc (num_sectors * sector_nsteps , sizeof (phys_addr_t ), GFP_NOFS );
1039+ rbio -> stripe_paddrs = kcalloc (num_sectors * sector_nsteps , sizeof (phys_addr_t ), GFP_NOFS );
10121040 rbio -> finish_pointers = kcalloc (real_stripes , sizeof (void * ), GFP_NOFS );
10131041 rbio -> error_bitmap = bitmap_zalloc (num_sectors , GFP_NOFS );
10141042 rbio -> stripe_uptodate_bitmap = bitmap_zalloc (num_sectors , GFP_NOFS );
@@ -1019,7 +1047,7 @@ static struct btrfs_raid_bio *alloc_rbio(struct btrfs_fs_info *fs_info,
10191047 kfree (rbio );
10201048 return ERR_PTR (- ENOMEM );
10211049 }
1022- for (int i = 0 ; i < num_sectors ; i ++ ) {
1050+ for (int i = 0 ; i < num_sectors * sector_nsteps ; i ++ ) {
10231051 rbio -> stripe_paddrs [i ] = INVALID_PADDR ;
10241052 rbio -> bio_paddrs [i ] = INVALID_PADDR ;
10251053 }
@@ -1037,6 +1065,7 @@ static struct btrfs_raid_bio *alloc_rbio(struct btrfs_fs_info *fs_info,
10371065 rbio -> real_stripes = real_stripes ;
10381066 rbio -> stripe_npages = stripe_npages ;
10391067 rbio -> stripe_nsectors = stripe_nsectors ;
1068+ rbio -> sector_nsteps = sector_nsteps ;
10401069 refcount_set (& rbio -> refs , 1 );
10411070 atomic_set (& rbio -> stripes_pending , 0 );
10421071
@@ -1192,18 +1221,19 @@ static int rbio_add_io_paddr(struct btrfs_raid_bio *rbio, struct bio_list *bio_l
11921221
11931222static void index_one_bio (struct btrfs_raid_bio * rbio , struct bio * bio )
11941223{
1195- const u32 sectorsize = rbio -> bioc -> fs_info -> sectorsize ;
1196- const u32 sectorsize_bits = rbio -> bioc -> fs_info -> sectorsize_bits ;
1224+ struct btrfs_fs_info * fs_info = rbio -> bioc -> fs_info ;
1225+ const u32 step = min (fs_info -> sectorsize , PAGE_SIZE );
1226+ const u32 step_bits = min (fs_info -> sectorsize_bits , PAGE_SHIFT );
11971227 struct bvec_iter iter = bio -> bi_iter ;
11981228 phys_addr_t paddr ;
11991229 u32 offset = (bio -> bi_iter .bi_sector << SECTOR_SHIFT ) -
12001230 rbio -> bioc -> full_stripe_logical ;
12011231
1202- btrfs_bio_for_each_block (paddr , bio , & iter , sectorsize ) {
1203- unsigned int index = (offset >> sectorsize_bits );
1232+ btrfs_bio_for_each_block (paddr , bio , & iter , step ) {
1233+ unsigned int index = (offset >> step_bits );
12041234
12051235 rbio -> bio_paddrs [index ] = paddr ;
1206- offset += sectorsize ;
1236+ offset += step ;
12071237 }
12081238}
12091239
@@ -1303,7 +1333,7 @@ static void generate_pq_vertical(struct btrfs_raid_bio *rbio, int sectornr)
13031333 sector_paddr_in_rbio (rbio , stripe , sectornr , 0 ));
13041334
13051335 /* Then add the parity stripe */
1306- set_bit (rbio_stripe_sector_index (rbio , rbio -> nr_data , sectornr ),
1336+ set_bit (rbio_sector_index (rbio , rbio -> nr_data , sectornr ),
13071337 rbio -> stripe_uptodate_bitmap );
13081338 pointers [stripe ++ ] = kmap_local_paddr (rbio_pstripe_paddr (rbio , sectornr ));
13091339
@@ -1312,7 +1342,7 @@ static void generate_pq_vertical(struct btrfs_raid_bio *rbio, int sectornr)
13121342 * RAID6, add the qstripe and call the library function
13131343 * to fill in our p/q
13141344 */
1315- set_bit (rbio_stripe_sector_index (rbio , rbio -> nr_data + 1 , sectornr ),
1345+ set_bit (rbio_sector_index (rbio , rbio -> nr_data + 1 , sectornr ),
13161346 rbio -> stripe_uptodate_bitmap );
13171347 pointers [stripe ++ ] = kmap_local_paddr (rbio_qstripe_paddr (rbio , sectornr ));
13181348
@@ -1932,15 +1962,15 @@ static int recover_vertical(struct btrfs_raid_bio *rbio, int sector_nr,
19321962 if (ret < 0 )
19331963 goto cleanup ;
19341964
1935- set_bit (rbio_stripe_sector_index (rbio , faila , sector_nr ),
1965+ set_bit (rbio_sector_index (rbio , faila , sector_nr ),
19361966 rbio -> stripe_uptodate_bitmap );
19371967 }
19381968 if (failb >= 0 ) {
19391969 ret = verify_one_sector (rbio , failb , sector_nr );
19401970 if (ret < 0 )
19411971 goto cleanup ;
19421972
1943- set_bit (rbio_stripe_sector_index (rbio , failb , sector_nr ),
1973+ set_bit (rbio_sector_index (rbio , failb , sector_nr ),
19441974 rbio -> stripe_uptodate_bitmap );
19451975 }
19461976
@@ -2288,7 +2318,7 @@ static bool need_read_stripe_sectors(struct btrfs_raid_bio *rbio)
22882318 int i ;
22892319
22902320 for (i = 0 ; i < rbio -> nr_data * rbio -> stripe_nsectors ; i ++ ) {
2291- phys_addr_t paddr = rbio -> stripe_paddrs [i ];
2321+ phys_addr_t paddr = rbio -> stripe_paddrs [i * rbio -> sector_nsteps ];
22922322
22932323 /*
22942324 * We have a sector which doesn't have page nor uptodate,
@@ -2746,7 +2776,7 @@ static int scrub_assemble_read_bios(struct btrfs_raid_bio *rbio)
27462776 * The bio cache may have handed us an uptodate sector. If so,
27472777 * use it.
27482778 */
2749- if (test_bit (rbio_stripe_sector_index (rbio , stripe , sectornr ),
2779+ if (test_bit (rbio_sector_index (rbio , stripe , sectornr ),
27502780 rbio -> stripe_uptodate_bitmap ))
27512781 continue ;
27522782
0 commit comments