@@ -1245,17 +1245,41 @@ static int get_rbio_vertical_errors(struct btrfs_raid_bio *rbio, int sector_nr,
12451245 return found_errors ;
12461246}
12471247
1248+ static int bio_add_paddrs (struct bio * bio , phys_addr_t * paddrs , unsigned int nr_steps ,
1249+ unsigned int step )
1250+ {
1251+ int added = 0 ;
1252+ int ret ;
1253+
1254+ for (int i = 0 ; i < nr_steps ; i ++ ) {
1255+ ret = bio_add_page (bio , phys_to_page (paddrs [i ]), step ,
1256+ offset_in_page (paddrs [i ]));
1257+ if (ret != step )
1258+ goto revert ;
1259+ added += ret ;
1260+ }
1261+ return added ;
1262+ revert :
1263+ /*
1264+ * We don't need to revert the bvec, as the bio will be submitted immediately,
1265+ * as long as the size is reduced the extra bvec will not be accessed.
1266+ */
1267+ bio -> bi_iter .bi_size -= added ;
1268+ return 0 ;
1269+ }
1270+
12481271/*
12491272 * Add a single sector @sector into our list of bios for IO.
12501273 *
12511274 * Return 0 if everything went well.
1252- * Return <0 for error.
1275+ * Return <0 for error, and no byte will be added to @rbio .
12531276 */
1254- static int rbio_add_io_paddr (struct btrfs_raid_bio * rbio , struct bio_list * bio_list ,
1255- phys_addr_t paddr , unsigned int stripe_nr ,
1256- unsigned int sector_nr , enum req_op op )
1277+ static int rbio_add_io_paddrs (struct btrfs_raid_bio * rbio , struct bio_list * bio_list ,
1278+ phys_addr_t * paddrs , unsigned int stripe_nr ,
1279+ unsigned int sector_nr , enum req_op op )
12571280{
12581281 const u32 sectorsize = rbio -> bioc -> fs_info -> sectorsize ;
1282+ const u32 step = min (sectorsize , PAGE_SIZE );
12591283 struct bio * last = bio_list -> tail ;
12601284 int ret ;
12611285 struct bio * bio ;
@@ -1271,7 +1295,7 @@ static int rbio_add_io_paddr(struct btrfs_raid_bio *rbio, struct bio_list *bio_l
12711295 rbio , stripe_nr );
12721296 ASSERT_RBIO_SECTOR (sector_nr >= 0 && sector_nr < rbio -> stripe_nsectors ,
12731297 rbio , sector_nr );
1274- ASSERT (paddr != INVALID_PADDR );
1298+ ASSERT (paddrs != NULL );
12751299
12761300 stripe = & rbio -> bioc -> stripes [stripe_nr ];
12771301 disk_start = stripe -> physical + sector_nr * sectorsize ;
@@ -1302,8 +1326,7 @@ static int rbio_add_io_paddr(struct btrfs_raid_bio *rbio, struct bio_list *bio_l
13021326 */
13031327 if (last_end == disk_start && !last -> bi_status &&
13041328 last -> bi_bdev == stripe -> dev -> bdev ) {
1305- ret = bio_add_page (last , phys_to_page (paddr ), sectorsize ,
1306- offset_in_page (paddr ));
1329+ ret = bio_add_paddrs (last , paddrs , rbio -> sector_nsteps , step );
13071330 if (ret == sectorsize )
13081331 return 0 ;
13091332 }
@@ -1316,7 +1339,8 @@ static int rbio_add_io_paddr(struct btrfs_raid_bio *rbio, struct bio_list *bio_l
13161339 bio -> bi_iter .bi_sector = disk_start >> SECTOR_SHIFT ;
13171340 bio -> bi_private = rbio ;
13181341
1319- __bio_add_page (bio , phys_to_page (paddr ), sectorsize , offset_in_page (paddr ));
1342+ ret = bio_add_paddrs (bio , paddrs , rbio -> sector_nsteps , step );
1343+ ASSERT (ret == sectorsize );
13201344 bio_list_add (bio_list , bio );
13211345 return 0 ;
13221346}
@@ -1497,7 +1521,7 @@ static int rmw_assemble_write_bios(struct btrfs_raid_bio *rbio,
14971521 */
14981522 for (total_sector_nr = 0 ; total_sector_nr < rbio -> nr_sectors ;
14991523 total_sector_nr ++ ) {
1500- phys_addr_t paddr ;
1524+ phys_addr_t * paddrs ;
15011525
15021526 stripe = total_sector_nr / rbio -> stripe_nsectors ;
15031527 sectornr = total_sector_nr % rbio -> stripe_nsectors ;
@@ -1507,15 +1531,15 @@ static int rmw_assemble_write_bios(struct btrfs_raid_bio *rbio,
15071531 continue ;
15081532
15091533 if (stripe < rbio -> nr_data ) {
1510- paddr = sector_paddr_in_rbio (rbio , stripe , sectornr , 1 );
1511- if (paddr == INVALID_PADDR )
1534+ paddrs = sector_paddrs_in_rbio (rbio , stripe , sectornr , 1 );
1535+ if (paddrs == NULL )
15121536 continue ;
15131537 } else {
1514- paddr = rbio_stripe_paddr (rbio , stripe , sectornr );
1538+ paddrs = rbio_stripe_paddrs (rbio , stripe , sectornr );
15151539 }
15161540
1517- ret = rbio_add_io_paddr (rbio , bio_list , paddr , stripe ,
1518- sectornr , REQ_OP_WRITE );
1541+ ret = rbio_add_io_paddrs (rbio , bio_list , paddrs , stripe ,
1542+ sectornr , REQ_OP_WRITE );
15191543 if (ret )
15201544 goto error ;
15211545 }
@@ -1532,7 +1556,7 @@ static int rmw_assemble_write_bios(struct btrfs_raid_bio *rbio,
15321556
15331557 for (total_sector_nr = 0 ; total_sector_nr < rbio -> nr_sectors ;
15341558 total_sector_nr ++ ) {
1535- phys_addr_t paddr ;
1559+ phys_addr_t * paddrs ;
15361560
15371561 stripe = total_sector_nr / rbio -> stripe_nsectors ;
15381562 sectornr = total_sector_nr % rbio -> stripe_nsectors ;
@@ -1557,14 +1581,14 @@ static int rmw_assemble_write_bios(struct btrfs_raid_bio *rbio,
15571581 continue ;
15581582
15591583 if (stripe < rbio -> nr_data ) {
1560- paddr = sector_paddr_in_rbio (rbio , stripe , sectornr , 1 );
1561- if (paddr == INVALID_PADDR )
1584+ paddrs = sector_paddrs_in_rbio (rbio , stripe , sectornr , 1 );
1585+ if (paddrs == NULL )
15621586 continue ;
15631587 } else {
1564- paddr = rbio_stripe_paddr (rbio , stripe , sectornr );
1588+ paddrs = rbio_stripe_paddrs (rbio , stripe , sectornr );
15651589 }
15661590
1567- ret = rbio_add_io_paddr (rbio , bio_list , paddr ,
1591+ ret = rbio_add_io_paddrs (rbio , bio_list , paddrs ,
15681592 rbio -> real_stripes ,
15691593 sectornr , REQ_OP_WRITE );
15701594 if (ret )
@@ -2184,7 +2208,7 @@ static void recover_rbio(struct btrfs_raid_bio *rbio)
21842208 total_sector_nr ++ ) {
21852209 int stripe = total_sector_nr / rbio -> stripe_nsectors ;
21862210 int sectornr = total_sector_nr % rbio -> stripe_nsectors ;
2187- phys_addr_t paddr ;
2211+ phys_addr_t * paddrs ;
21882212
21892213 /*
21902214 * Skip the range which has error. It can be a range which is
@@ -2201,9 +2225,9 @@ static void recover_rbio(struct btrfs_raid_bio *rbio)
22012225 continue ;
22022226 }
22032227
2204- paddr = rbio_stripe_paddr (rbio , stripe , sectornr );
2205- ret = rbio_add_io_paddr (rbio , & bio_list , paddr , stripe ,
2206- sectornr , REQ_OP_READ );
2228+ paddrs = rbio_stripe_paddrs (rbio , stripe , sectornr );
2229+ ret = rbio_add_io_paddrs (rbio , & bio_list , paddrs , stripe ,
2230+ sectornr , REQ_OP_READ );
22072231 if (ret < 0 ) {
22082232 bio_list_put (& bio_list );
22092233 goto out ;
@@ -2393,11 +2417,11 @@ static int rmw_read_wait_recover(struct btrfs_raid_bio *rbio)
23932417 total_sector_nr ++ ) {
23942418 int stripe = total_sector_nr / rbio -> stripe_nsectors ;
23952419 int sectornr = total_sector_nr % rbio -> stripe_nsectors ;
2396- phys_addr_t paddr ;
2420+ phys_addr_t * paddrs ;
23972421
2398- paddr = rbio_stripe_paddr (rbio , stripe , sectornr );
2399- ret = rbio_add_io_paddr (rbio , & bio_list , paddr , stripe ,
2400- sectornr , REQ_OP_READ );
2422+ paddrs = rbio_stripe_paddrs (rbio , stripe , sectornr );
2423+ ret = rbio_add_io_paddrs (rbio , & bio_list , paddrs , stripe ,
2424+ sectornr , REQ_OP_READ );
24012425 if (ret ) {
24022426 bio_list_put (& bio_list );
24032427 return ret ;
@@ -2751,11 +2775,11 @@ static int finish_parity_scrub(struct btrfs_raid_bio *rbio)
27512775 * everything else.
27522776 */
27532777 for_each_set_bit (sectornr , & rbio -> dbitmap , rbio -> stripe_nsectors ) {
2754- phys_addr_t paddr ;
2778+ phys_addr_t * paddrs ;
27552779
2756- paddr = rbio_stripe_paddr (rbio , rbio -> scrubp , sectornr );
2757- ret = rbio_add_io_paddr (rbio , & bio_list , paddr , rbio -> scrubp ,
2758- sectornr , REQ_OP_WRITE );
2780+ paddrs = rbio_stripe_paddrs (rbio , rbio -> scrubp , sectornr );
2781+ ret = rbio_add_io_paddrs (rbio , & bio_list , paddrs , rbio -> scrubp ,
2782+ sectornr , REQ_OP_WRITE );
27592783 if (ret )
27602784 goto cleanup ;
27612785 }
@@ -2769,11 +2793,11 @@ static int finish_parity_scrub(struct btrfs_raid_bio *rbio)
27692793 */
27702794 ASSERT_RBIO (rbio -> bioc -> replace_stripe_src >= 0 , rbio );
27712795 for_each_set_bit (sectornr , pbitmap , rbio -> stripe_nsectors ) {
2772- phys_addr_t paddr ;
2796+ phys_addr_t * paddrs ;
27732797
2774- paddr = rbio_stripe_paddr (rbio , rbio -> scrubp , sectornr );
2775- ret = rbio_add_io_paddr (rbio , & bio_list , paddr , rbio -> real_stripes ,
2776- sectornr , REQ_OP_WRITE );
2798+ paddrs = rbio_stripe_paddrs (rbio , rbio -> scrubp , sectornr );
2799+ ret = rbio_add_io_paddrs (rbio , & bio_list , paddrs , rbio -> real_stripes ,
2800+ sectornr , REQ_OP_WRITE );
27772801 if (ret )
27782802 goto cleanup ;
27792803 }
@@ -2889,7 +2913,7 @@ static int scrub_assemble_read_bios(struct btrfs_raid_bio *rbio)
28892913 total_sector_nr ++ ) {
28902914 int sectornr = total_sector_nr % rbio -> stripe_nsectors ;
28912915 int stripe = total_sector_nr / rbio -> stripe_nsectors ;
2892- phys_addr_t paddr ;
2916+ phys_addr_t * paddrs ;
28932917
28942918 /* No data in the vertical stripe, no need to read. */
28952919 if (!test_bit (sectornr , & rbio -> dbitmap ))
@@ -2900,11 +2924,11 @@ static int scrub_assemble_read_bios(struct btrfs_raid_bio *rbio)
29002924 * read them from the disk. If sector_paddr_in_rbio() finds a sector
29012925 * in the bio list we don't need to read it off the stripe.
29022926 */
2903- paddr = sector_paddr_in_rbio (rbio , stripe , sectornr , 1 );
2904- if (paddr == INVALID_PADDR )
2927+ paddrs = sector_paddrs_in_rbio (rbio , stripe , sectornr , 1 );
2928+ if (paddrs == NULL )
29052929 continue ;
29062930
2907- paddr = rbio_stripe_paddr (rbio , stripe , sectornr );
2931+ paddrs = rbio_stripe_paddrs (rbio , stripe , sectornr );
29082932 /*
29092933 * The bio cache may have handed us an uptodate sector. If so,
29102934 * use it.
@@ -2913,8 +2937,8 @@ static int scrub_assemble_read_bios(struct btrfs_raid_bio *rbio)
29132937 rbio -> stripe_uptodate_bitmap ))
29142938 continue ;
29152939
2916- ret = rbio_add_io_paddr (rbio , & bio_list , paddr , stripe ,
2917- sectornr , REQ_OP_READ );
2940+ ret = rbio_add_io_paddrs (rbio , & bio_list , paddrs , stripe ,
2941+ sectornr , REQ_OP_READ );
29182942 if (ret ) {
29192943 bio_list_put (& bio_list );
29202944 return ret ;
0 commit comments