diff options
Diffstat (limited to 'drivers/md/dm.c')
-rw-r--r-- | drivers/md/dm.c | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index d67c95ef8d7e..2b53c3841b53 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -1320,7 +1320,7 @@ static int clone_bio(struct dm_target_io *tio, struct bio *bio, | |||
1320 | 1320 | ||
1321 | __bio_clone_fast(clone, bio); | 1321 | __bio_clone_fast(clone, bio); |
1322 | 1322 | ||
1323 | if (unlikely(bio_integrity(bio) != NULL)) { | 1323 | if (bio_integrity(bio)) { |
1324 | int r; | 1324 | int r; |
1325 | 1325 | ||
1326 | if (unlikely(!dm_target_has_integrity(tio->ti->type) && | 1326 | if (unlikely(!dm_target_has_integrity(tio->ti->type) && |
@@ -1336,11 +1336,7 @@ static int clone_bio(struct dm_target_io *tio, struct bio *bio, | |||
1336 | return r; | 1336 | return r; |
1337 | } | 1337 | } |
1338 | 1338 | ||
1339 | bio_advance(clone, to_bytes(sector - clone->bi_iter.bi_sector)); | 1339 | bio_trim(clone, sector - clone->bi_iter.bi_sector, len); |
1340 | clone->bi_iter.bi_size = to_bytes(len); | ||
1341 | |||
1342 | if (unlikely(bio_integrity(bio) != NULL)) | ||
1343 | bio_integrity_trim(clone); | ||
1344 | 1340 | ||
1345 | return 0; | 1341 | return 0; |
1346 | } | 1342 | } |
@@ -1588,6 +1584,9 @@ static void init_clone_info(struct clone_info *ci, struct mapped_device *md, | |||
1588 | ci->sector = bio->bi_iter.bi_sector; | 1584 | ci->sector = bio->bi_iter.bi_sector; |
1589 | } | 1585 | } |
1590 | 1586 | ||
1587 | #define __dm_part_stat_sub(part, field, subnd) \ | ||
1588 | (part_stat_get(part, field) -= (subnd)) | ||
1589 | |||
1591 | /* | 1590 | /* |
1592 | * Entry point to split a bio into clones and submit them to the targets. | 1591 | * Entry point to split a bio into clones and submit them to the targets. |
1593 | */ | 1592 | */ |
@@ -1642,7 +1641,21 @@ static blk_qc_t __split_and_process_bio(struct mapped_device *md, | |||
1642 | struct bio *b = bio_split(bio, bio_sectors(bio) - ci.sector_count, | 1641 | struct bio *b = bio_split(bio, bio_sectors(bio) - ci.sector_count, |
1643 | GFP_NOIO, &md->queue->bio_split); | 1642 | GFP_NOIO, &md->queue->bio_split); |
1644 | ci.io->orig_bio = b; | 1643 | ci.io->orig_bio = b; |
1644 | |||
1645 | /* | ||
1646 | * Adjust IO stats for each split, otherwise upon queue | ||
1647 | * reentry there will be redundant IO accounting. | ||
1648 | * NOTE: this is a stop-gap fix, a proper fix involves | ||
1649 | * significant refactoring of DM core's bio splitting | ||
1650 | * (by eliminating DM's splitting and just using bio_split) | ||
1651 | */ | ||
1652 | part_stat_lock(); | ||
1653 | __dm_part_stat_sub(&dm_disk(md)->part0, | ||
1654 | sectors[op_stat_group(bio_op(bio))], ci.sector_count); | ||
1655 | part_stat_unlock(); | ||
1656 | |||
1645 | bio_chain(b, bio); | 1657 | bio_chain(b, bio); |
1658 | trace_block_split(md->queue, b, bio->bi_iter.bi_sector); | ||
1646 | ret = generic_make_request(bio); | 1659 | ret = generic_make_request(bio); |
1647 | break; | 1660 | break; |
1648 | } | 1661 | } |
@@ -1713,6 +1726,15 @@ out: | |||
1713 | return ret; | 1726 | return ret; |
1714 | } | 1727 | } |
1715 | 1728 | ||
1729 | static blk_qc_t dm_process_bio(struct mapped_device *md, | ||
1730 | struct dm_table *map, struct bio *bio) | ||
1731 | { | ||
1732 | if (dm_get_md_type(md) == DM_TYPE_NVME_BIO_BASED) | ||
1733 | return __process_bio(md, map, bio); | ||
1734 | else | ||
1735 | return __split_and_process_bio(md, map, bio); | ||
1736 | } | ||
1737 | |||
1716 | static blk_qc_t dm_make_request(struct request_queue *q, struct bio *bio) | 1738 | static blk_qc_t dm_make_request(struct request_queue *q, struct bio *bio) |
1717 | { | 1739 | { |
1718 | struct mapped_device *md = q->queuedata; | 1740 | struct mapped_device *md = q->queuedata; |
@@ -1733,10 +1755,7 @@ static blk_qc_t dm_make_request(struct request_queue *q, struct bio *bio) | |||
1733 | return ret; | 1755 | return ret; |
1734 | } | 1756 | } |
1735 | 1757 | ||
1736 | if (dm_get_md_type(md) == DM_TYPE_NVME_BIO_BASED) | 1758 | ret = dm_process_bio(md, map, bio); |
1737 | ret = __process_bio(md, map, bio); | ||
1738 | else | ||
1739 | ret = __split_and_process_bio(md, map, bio); | ||
1740 | 1759 | ||
1741 | dm_put_live_table(md, srcu_idx); | 1760 | dm_put_live_table(md, srcu_idx); |
1742 | return ret; | 1761 | return ret; |
@@ -2415,9 +2434,9 @@ static void dm_wq_work(struct work_struct *work) | |||
2415 | break; | 2434 | break; |
2416 | 2435 | ||
2417 | if (dm_request_based(md)) | 2436 | if (dm_request_based(md)) |
2418 | generic_make_request(c); | 2437 | (void) generic_make_request(c); |
2419 | else | 2438 | else |
2420 | __split_and_process_bio(md, map, c); | 2439 | (void) dm_process_bio(md, map, c); |
2421 | } | 2440 | } |
2422 | 2441 | ||
2423 | dm_put_live_table(md, srcu_idx); | 2442 | dm_put_live_table(md, srcu_idx); |