@@ -360,16 +360,20 @@ static int dm_update_zone_wp_offset(struct mapped_device *md, unsigned int zno,
360360 return 0 ;
361361}
362362
363+ struct orig_bio_details {
364+ unsigned int op ;
365+ unsigned int nr_sectors ;
366+ };
367+
363368/*
364369 * First phase of BIO mapping for targets with zone append emulation:
365370 * check all BIO that change a zone writer pointer and change zone
366371 * append operations into regular write operations.
367372 */
368373static bool dm_zone_map_bio_begin (struct mapped_device * md ,
369- struct bio * orig_bio , struct bio * clone )
374+ unsigned int zno , struct bio * clone )
370375{
371376 sector_t zsectors = blk_queue_zone_sectors (md -> queue );
372- unsigned int zno = bio_zone_no (orig_bio );
373377 unsigned int zwp_offset = READ_ONCE (md -> zwp_offset [zno ]);
374378
375379 /*
@@ -384,7 +388,7 @@ static bool dm_zone_map_bio_begin(struct mapped_device *md,
384388 WRITE_ONCE (md -> zwp_offset [zno ], zwp_offset );
385389 }
386390
387- switch (bio_op (orig_bio )) {
391+ switch (bio_op (clone )) {
388392 case REQ_OP_ZONE_RESET :
389393 case REQ_OP_ZONE_FINISH :
390394 return true;
@@ -401,9 +405,8 @@ static bool dm_zone_map_bio_begin(struct mapped_device *md,
401405 * target zone.
402406 */
403407 clone -> bi_opf = REQ_OP_WRITE | REQ_NOMERGE |
404- (orig_bio -> bi_opf & (~REQ_OP_MASK ));
405- clone -> bi_iter .bi_sector =
406- orig_bio -> bi_iter .bi_sector + zwp_offset ;
408+ (clone -> bi_opf & (~REQ_OP_MASK ));
409+ clone -> bi_iter .bi_sector += zwp_offset ;
407410 break ;
408411 default :
409412 DMWARN_LIMIT ("Invalid BIO operation" );
@@ -423,19 +426,18 @@ static bool dm_zone_map_bio_begin(struct mapped_device *md,
423426 * data written to a zone. Note that at this point, the remapped clone BIO
424427 * may already have completed, so we do not touch it.
425428 */
426- static blk_status_t dm_zone_map_bio_end (struct mapped_device * md ,
427- struct bio * orig_bio ,
429+ static blk_status_t dm_zone_map_bio_end (struct mapped_device * md , unsigned int zno ,
430+ struct orig_bio_details * orig_bio_details ,
428431 unsigned int nr_sectors )
429432{
430- unsigned int zno = bio_zone_no (orig_bio );
431433 unsigned int zwp_offset = READ_ONCE (md -> zwp_offset [zno ]);
432434
433435 /* The clone BIO may already have been completed and failed */
434436 if (zwp_offset == DM_ZONE_INVALID_WP_OFST )
435437 return BLK_STS_IOERR ;
436438
437439 /* Update the zone wp offset */
438- switch (bio_op ( orig_bio ) ) {
440+ switch (orig_bio_details -> op ) {
439441 case REQ_OP_ZONE_RESET :
440442 WRITE_ONCE (md -> zwp_offset [zno ], 0 );
441443 return BLK_STS_OK ;
@@ -452,7 +454,7 @@ static blk_status_t dm_zone_map_bio_end(struct mapped_device *md,
452454 * Check that the target did not truncate the write operation
453455 * emulating a zone append.
454456 */
455- if (nr_sectors != bio_sectors ( orig_bio ) ) {
457+ if (nr_sectors != orig_bio_details -> nr_sectors ) {
456458 DMWARN_LIMIT ("Truncated write for zone append" );
457459 return BLK_STS_IOERR ;
458460 }
@@ -488,23 +490,23 @@ static inline void dm_zone_unlock(struct request_queue *q,
488490 bio_clear_flag (clone , BIO_ZONE_WRITE_LOCKED );
489491}
490492
491- static bool dm_need_zone_wp_tracking (struct bio * orig_bio )
493+ static bool dm_need_zone_wp_tracking (struct bio * bio )
492494{
493495 /*
494496 * Special processing is not needed for operations that do not need the
495497 * zone write lock, that is, all operations that target conventional
496498 * zones and all operations that do not modify directly a sequential
497499 * zone write pointer.
498500 */
499- if (op_is_flush (orig_bio -> bi_opf ) && !bio_sectors (orig_bio ))
501+ if (op_is_flush (bio -> bi_opf ) && !bio_sectors (bio ))
500502 return false;
501- switch (bio_op (orig_bio )) {
503+ switch (bio_op (bio )) {
502504 case REQ_OP_WRITE_ZEROES :
503505 case REQ_OP_WRITE :
504506 case REQ_OP_ZONE_RESET :
505507 case REQ_OP_ZONE_FINISH :
506508 case REQ_OP_ZONE_APPEND :
507- return bio_zone_is_seq (orig_bio );
509+ return bio_zone_is_seq (bio );
508510 default :
509511 return false;
510512 }
@@ -519,8 +521,8 @@ int dm_zone_map_bio(struct dm_target_io *tio)
519521 struct dm_target * ti = tio -> ti ;
520522 struct mapped_device * md = io -> md ;
521523 struct request_queue * q = md -> queue ;
522- struct bio * orig_bio = io -> orig_bio ;
523524 struct bio * clone = & tio -> clone ;
525+ struct orig_bio_details orig_bio_details ;
524526 unsigned int zno ;
525527 blk_status_t sts ;
526528 int r ;
@@ -529,18 +531,21 @@ int dm_zone_map_bio(struct dm_target_io *tio)
529531 * IOs that do not change a zone write pointer do not need
530532 * any additional special processing.
531533 */
532- if (!dm_need_zone_wp_tracking (orig_bio ))
534+ if (!dm_need_zone_wp_tracking (clone ))
533535 return ti -> type -> map (ti , clone );
534536
535537 /* Lock the target zone */
536- zno = bio_zone_no (orig_bio );
538+ zno = bio_zone_no (clone );
537539 dm_zone_lock (q , zno , clone );
538540
541+ orig_bio_details .nr_sectors = bio_sectors (clone );
542+ orig_bio_details .op = bio_op (clone );
543+
539544 /*
540545 * Check that the bio and the target zone write pointer offset are
541546 * both valid, and if the bio is a zone append, remap it to a write.
542547 */
543- if (!dm_zone_map_bio_begin (md , orig_bio , clone )) {
548+ if (!dm_zone_map_bio_begin (md , zno , clone )) {
544549 dm_zone_unlock (q , zno , clone );
545550 return DM_MAPIO_KILL ;
546551 }
@@ -560,15 +565,17 @@ int dm_zone_map_bio(struct dm_target_io *tio)
560565 * The target submitted the clone BIO. The target zone will
561566 * be unlocked on completion of the clone.
562567 */
563- sts = dm_zone_map_bio_end (md , orig_bio , * tio -> len_ptr );
568+ sts = dm_zone_map_bio_end (md , zno , & orig_bio_details ,
569+ * tio -> len_ptr );
564570 break ;
565571 case DM_MAPIO_REMAPPED :
566572 /*
567573 * The target only remapped the clone BIO. In case of error,
568574 * unlock the target zone here as the clone will not be
569575 * submitted.
570576 */
571- sts = dm_zone_map_bio_end (md , orig_bio , * tio -> len_ptr );
577+ sts = dm_zone_map_bio_end (md , zno , & orig_bio_details ,
578+ * tio -> len_ptr );
572579 if (sts != BLK_STS_OK )
573580 dm_zone_unlock (q , zno , clone );
574581 break ;
0 commit comments