From 854fbb9c699e34fe4889e6907c4fc73889192223 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Wed, 11 Feb 2015 08:20:13 -0700 Subject: [PATCH] block: prevent request-to-request merging with gaps if not allowed If the queue has SG_GAPS set, we must not merge across an sg gap. This is caught for the bio case, but currently not for the more rare case of merging two requests directly. Signed-off-by: Keith Busch Cut the dm bits, those will go through the dm tree, and fixed the test_bit() test. Signed-off-by: Jens Axboe --- block/blk-merge.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/block/blk-merge.c b/block/blk-merge.c index 89b97b5..9476b15 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -385,6 +385,14 @@ static bool req_no_special_merge(struct request *req) return !q->mq_ops && req->special; } +static int req_gap_to_prev(struct request *req, struct request *next) +{ + struct bio *prev = req->biotail; + + return bvec_gap_to_prev(&prev->bi_io_vec[prev->bi_vcnt - 1], + next->bio->bi_io_vec[0].bv_offset); +} + static int ll_merge_requests_fn(struct request_queue *q, struct request *req, struct request *next) { @@ -399,6 +407,10 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req, if (req_no_special_merge(req) || req_no_special_merge(next)) return 0; + if (test_bit(QUEUE_FLAG_SG_GAPS, &q->queue_flags) && + req_gap_to_prev(req, next)) + return 0; + /* * Will it become too large? */ -- 2.7.4