|
@@ -1498,8 +1498,29 @@ static void __split_and_process_bio(struct mapped_device *md,
|
|
|
} else {
|
|
|
ci.bio = bio;
|
|
|
ci.sector_count = bio_sectors(bio);
|
|
|
- while (ci.sector_count && !error)
|
|
|
+ while (ci.sector_count && !error) {
|
|
|
error = __split_and_process_non_flush(&ci);
|
|
|
+ if (current->bio_list && ci.sector_count && !error) {
|
|
|
+ /*
|
|
|
+ * Remainder must be passed to generic_make_request()
|
|
|
+ * so that it gets handled *after* bios already submitted
|
|
|
+ * have been completely processed.
|
|
|
+ * We take a clone of the original to store in
|
|
|
+ * ci.io->bio to be used by end_io_acct() and
|
|
|
+ * for dec_pending to use for completion handling.
|
|
|
+ * As this path is not used for REQ_OP_ZONE_REPORT,
|
|
|
+ * the usage of io->bio in dm_remap_zone_report()
|
|
|
+ * won't be affected by this reassignment.
|
|
|
+ */
|
|
|
+ struct bio *b = bio_clone_bioset(bio, GFP_NOIO,
|
|
|
+ md->queue->bio_split);
|
|
|
+ ci.io->bio = b;
|
|
|
+ bio_advance(bio, (bio_sectors(bio) - ci.sector_count) << 9);
|
|
|
+ bio_chain(b, bio);
|
|
|
+ generic_make_request(bio);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/* drop the extra reference count */
|
|
@@ -1510,8 +1531,8 @@ static void __split_and_process_bio(struct mapped_device *md,
|
|
|
*---------------------------------------------------------------*/
|
|
|
|
|
|
/*
|
|
|
- * The request function that just remaps the bio built up by
|
|
|
- * dm_merge_bvec.
|
|
|
+ * The request function that remaps the bio to one target and
|
|
|
+ * splits off any remainder.
|
|
|
*/
|
|
|
static blk_qc_t dm_make_request(struct request_queue *q, struct bio *bio)
|
|
|
{
|
|
@@ -2034,12 +2055,6 @@ int dm_setup_md_queue(struct mapped_device *md, struct dm_table *t)
|
|
|
case DM_TYPE_DAX_BIO_BASED:
|
|
|
dm_init_normal_md_queue(md);
|
|
|
blk_queue_make_request(md->queue, dm_make_request);
|
|
|
- /*
|
|
|
- * DM handles splitting bios as needed. Free the bio_split bioset
|
|
|
- * since it won't be used (saves 1 process per bio-based DM device).
|
|
|
- */
|
|
|
- bioset_free(md->queue->bio_split);
|
|
|
- md->queue->bio_split = NULL;
|
|
|
|
|
|
if (type == DM_TYPE_DAX_BIO_BASED)
|
|
|
queue_flag_set_unlocked(QUEUE_FLAG_DAX, md->queue);
|