From 17007f3994cdb4643355c73f54f0adad006cf59e Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Wed, 20 Jul 2016 21:40:47 -0600 Subject: [PATCH] block: Fix front merge check For a front merge, the maximum number of sectors of the request must be checked against the front merge BIO sector, not the current sector of the request. Signed-off-by: Damien Le Moal Reviewed-by: Hannes Reinecke Signed-off-by: Jens Axboe --- block/blk-merge.c | 6 +++--- include/linux/blkdev.h | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/block/blk-merge.c b/block/blk-merge.c index e7c2fbc3f656..5e4d93edeaf7 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -500,7 +500,7 @@ int ll_back_merge_fn(struct request_queue *q, struct request *req, integrity_req_gap_back_merge(req, bio)) return 0; if (blk_rq_sectors(req) + bio_sectors(bio) > - blk_rq_get_max_sectors(req)) { + blk_rq_get_max_sectors(req, blk_rq_pos(req))) { req->cmd_flags |= REQ_NOMERGE; if (req == q->last_merge) q->last_merge = NULL; @@ -524,7 +524,7 @@ int ll_front_merge_fn(struct request_queue *q, struct request *req, integrity_req_gap_front_merge(req, bio)) return 0; if (blk_rq_sectors(req) + bio_sectors(bio) > - blk_rq_get_max_sectors(req)) { + blk_rq_get_max_sectors(req, bio->bi_iter.bi_sector)) { req->cmd_flags |= REQ_NOMERGE; if (req == q->last_merge) q->last_merge = NULL; @@ -570,7 +570,7 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req, * Will it become too large? */ if ((blk_rq_sectors(req) + blk_rq_sectors(next)) > - blk_rq_get_max_sectors(req)) + blk_rq_get_max_sectors(req, blk_rq_pos(req))) return 0; total_phys_segments = req->nr_phys_segments + next->nr_phys_segments; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 9d84c98b5c79..48f05d768a53 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -922,7 +922,8 @@ static inline unsigned int blk_max_size_offset(struct request_queue *q, (offset & (q->limits.chunk_sectors - 1)); } -static inline unsigned int blk_rq_get_max_sectors(struct request *rq) +static inline unsigned int blk_rq_get_max_sectors(struct request *rq, + sector_t offset) { struct request_queue *q = rq->q; @@ -932,7 +933,7 @@ static inline unsigned int blk_rq_get_max_sectors(struct request *rq) if (!q->limits.chunk_sectors || (req_op(rq) == REQ_OP_DISCARD)) return blk_queue_get_max_sectors(q, req_op(rq)); - return min(blk_max_size_offset(q, blk_rq_pos(rq)), + return min(blk_max_size_offset(q, offset), blk_queue_get_max_sectors(q, req_op(rq))); }