diff options
author | Damien Le Moal <damien.lemoal@hgst.com> | 2016-07-20 23:40:47 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2016-07-20 23:40:47 -0400 |
commit | 17007f3994cdb4643355c73f54f0adad006cf59e (patch) | |
tree | ac5aab0bf6211f1dc878872db5ec73f9b99bda5b | |
parent | 72ef799b3f14f4cb4c56ba3af6e6bdcbae6df368 (diff) |
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 <damien.lemoal@hgst.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r-- | block/blk-merge.c | 6 | ||||
-rw-r--r-- | 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, | |||
500 | integrity_req_gap_back_merge(req, bio)) | 500 | integrity_req_gap_back_merge(req, bio)) |
501 | return 0; | 501 | return 0; |
502 | if (blk_rq_sectors(req) + bio_sectors(bio) > | 502 | if (blk_rq_sectors(req) + bio_sectors(bio) > |
503 | blk_rq_get_max_sectors(req)) { | 503 | blk_rq_get_max_sectors(req, blk_rq_pos(req))) { |
504 | req->cmd_flags |= REQ_NOMERGE; | 504 | req->cmd_flags |= REQ_NOMERGE; |
505 | if (req == q->last_merge) | 505 | if (req == q->last_merge) |
506 | q->last_merge = NULL; | 506 | q->last_merge = NULL; |
@@ -524,7 +524,7 @@ int ll_front_merge_fn(struct request_queue *q, struct request *req, | |||
524 | integrity_req_gap_front_merge(req, bio)) | 524 | integrity_req_gap_front_merge(req, bio)) |
525 | return 0; | 525 | return 0; |
526 | if (blk_rq_sectors(req) + bio_sectors(bio) > | 526 | if (blk_rq_sectors(req) + bio_sectors(bio) > |
527 | blk_rq_get_max_sectors(req)) { | 527 | blk_rq_get_max_sectors(req, bio->bi_iter.bi_sector)) { |
528 | req->cmd_flags |= REQ_NOMERGE; | 528 | req->cmd_flags |= REQ_NOMERGE; |
529 | if (req == q->last_merge) | 529 | if (req == q->last_merge) |
530 | q->last_merge = NULL; | 530 | q->last_merge = NULL; |
@@ -570,7 +570,7 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req, | |||
570 | * Will it become too large? | 570 | * Will it become too large? |
571 | */ | 571 | */ |
572 | if ((blk_rq_sectors(req) + blk_rq_sectors(next)) > | 572 | if ((blk_rq_sectors(req) + blk_rq_sectors(next)) > |
573 | blk_rq_get_max_sectors(req)) | 573 | blk_rq_get_max_sectors(req, blk_rq_pos(req))) |
574 | return 0; | 574 | return 0; |
575 | 575 | ||
576 | total_phys_segments = req->nr_phys_segments + next->nr_phys_segments; | 576 | 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, | |||
922 | (offset & (q->limits.chunk_sectors - 1)); | 922 | (offset & (q->limits.chunk_sectors - 1)); |
923 | } | 923 | } |
924 | 924 | ||
925 | static inline unsigned int blk_rq_get_max_sectors(struct request *rq) | 925 | static inline unsigned int blk_rq_get_max_sectors(struct request *rq, |
926 | sector_t offset) | ||
926 | { | 927 | { |
927 | struct request_queue *q = rq->q; | 928 | struct request_queue *q = rq->q; |
928 | 929 | ||
@@ -932,7 +933,7 @@ static inline unsigned int blk_rq_get_max_sectors(struct request *rq) | |||
932 | if (!q->limits.chunk_sectors || (req_op(rq) == REQ_OP_DISCARD)) | 933 | if (!q->limits.chunk_sectors || (req_op(rq) == REQ_OP_DISCARD)) |
933 | return blk_queue_get_max_sectors(q, req_op(rq)); | 934 | return blk_queue_get_max_sectors(q, req_op(rq)); |
934 | 935 | ||
935 | return min(blk_max_size_offset(q, blk_rq_pos(rq)), | 936 | return min(blk_max_size_offset(q, offset), |
936 | blk_queue_get_max_sectors(q, req_op(rq))); | 937 | blk_queue_get_max_sectors(q, req_op(rq))); |
937 | } | 938 | } |
938 | 939 | ||