block: Fix front merge check
authorDamien Le Moal <damien.lemoal@hgst.com>
Thu, 21 Jul 2016 03:40:47 +0000 (21:40 -0600)
committerJens Axboe <axboe@fb.com>
Thu, 21 Jul 2016 03:40:47 +0000 (21:40 -0600)
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>
block/blk-merge.c
include/linux/blkdev.h

index e7c2fbc3f6564055d4fc02c3288b0ce438a99e4f..5e4d93edeaf7cbb1c1e232ba8ea2ca5e6f7182c2 100644 (file)
@@ -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;
index 9d84c98b5c7974315e7161537e73b41af02c99b1..48f05d768a53bb4801d26d3a6c6a24d2fd628c27 100644 (file)
@@ -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)));
 }