diff options
author | Mike Snitzer <snitzer@redhat.com> | 2018-03-26 11:49:16 -0400 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2018-04-03 15:04:20 -0400 |
commit | 0519c71e8d461ac3ef9a555bb7339243c9128d37 (patch) | |
tree | 8c2b21667f734e23721a59bd16b36277ad19648d | |
parent | 880bcce0dcc3172fe865352b492c41d85290cb8d (diff) | |
download | linux-stable-0519c71e8d461ac3ef9a555bb7339243c9128d37.tar.gz linux-stable-0519c71e8d461ac3ef9a555bb7339243c9128d37.tar.bz2 linux-stable-0519c71e8d461ac3ef9a555bb7339243c9128d37.zip |
dm: backfill abnormal IO support to non-splitting IO submission
Otherwise, these abnormal IOs would be sent to the DM target
regardless of whether the target advertised support for them.
Factor out __process_abnormal_io() from __split_and_process_non_flush()
so that discards, write same, etc may be conditionally processed.
Fixes: 978e51ba3 ("dm: optimize bio-based NVMe IO submission")
Cc: stable@vger.kernel.org # 4.16
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
-rw-r--r-- | drivers/md/dm.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 353ea0ede091..038c7572fdd4 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1477,6 +1477,23 @@ static int __send_write_zeroes(struct clone_info *ci, struct dm_target *ti) return __send_changing_extent_only(ci, ti, get_num_write_zeroes_bios, NULL); } +static bool __process_abnormal_io(struct clone_info *ci, struct dm_target *ti, + int *result) +{ + struct bio *bio = ci->bio; + + if (bio_op(bio) == REQ_OP_DISCARD) + *result = __send_discard(ci, ti); + else if (bio_op(bio) == REQ_OP_WRITE_SAME) + *result = __send_write_same(ci, ti); + else if (bio_op(bio) == REQ_OP_WRITE_ZEROES) + *result = __send_write_zeroes(ci, ti); + else + return false; + + return true; +} + /* * Select the correct strategy for processing a non-flush bio. */ @@ -1491,12 +1508,8 @@ static int __split_and_process_non_flush(struct clone_info *ci) if (!dm_target_is_valid(ti)) return -EIO; - if (unlikely(bio_op(bio) == REQ_OP_DISCARD)) - return __send_discard(ci, ti); - else if (unlikely(bio_op(bio) == REQ_OP_WRITE_SAME)) - return __send_write_same(ci, ti); - else if (unlikely(bio_op(bio) == REQ_OP_WRITE_ZEROES)) - return __send_write_zeroes(ci, ti); + if (unlikely(__process_abnormal_io(ci, ti, &r))) + return r; if (bio_op(bio) == REQ_OP_ZONE_REPORT) len = ci->sector_count; @@ -1617,9 +1630,12 @@ static blk_qc_t __process_bio(struct mapped_device *md, goto out; } - tio = alloc_tio(&ci, ti, 0, GFP_NOIO); ci.bio = bio; ci.sector_count = bio_sectors(bio); + if (unlikely(__process_abnormal_io(&ci, ti, &error))) + goto out; + + tio = alloc_tio(&ci, ti, 0, GFP_NOIO); ret = __clone_and_map_simple_bio(&ci, tio, NULL); } out: |