You need to sign in or sign up before continuing.
提交 e8733450 编写于 作者: M Ming Lei 提交者: Cheng Jian

block: respect queue limit of max discard segment

mainline inclusion
from mainline-v5.9-rc3
commit 943b40c8
category: bugfix
bugzilla: 41908
CVE: NA

---------------------------

When queue_max_discard_segments(q) is 1, blk_discard_mergable() will
return false for discard request, then normal request merge is applied.
However, only queue_max_segments() is checked, so max discard segment
limit isn't respected.

Check max discard segment limit in the request merge code for fixing
the issue.

Discard request failure of virtio_blk is fixed.

Fixes: 69840466 ("block: fix the DISCARD request merge")
Signed-off-by: NMing Lei <ming.lei@redhat.com>
Reviewed-by: NChristoph Hellwig <hch@lst.de>
Cc: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: NJens Axboe <axboe@kernel.dk>

Conflict: block/blk-merge.c
Signed-off-by: NYu Kuai <yukuai3@huawei.com>
Reviewed-by: NYufen Yu <yuyufen@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
Signed-off-by: NCheng Jian <cj.chengjian@huawei.com>
上级 8ea9249f
...@@ -477,13 +477,20 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq, ...@@ -477,13 +477,20 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
} }
EXPORT_SYMBOL(blk_rq_map_sg); EXPORT_SYMBOL(blk_rq_map_sg);
static inline unsigned int blk_rq_get_max_segments(struct request *rq)
{
if (req_op(rq) == REQ_OP_DISCARD)
return queue_max_discard_segments(rq->q);
return queue_max_segments(rq->q);
}
static inline int ll_new_hw_segment(struct request_queue *q, static inline int ll_new_hw_segment(struct request_queue *q,
struct request *req, struct request *req,
struct bio *bio) struct bio *bio)
{ {
int nr_phys_segs = bio_phys_segments(q, bio); int nr_phys_segs = bio_phys_segments(q, bio);
if (req->nr_phys_segments + nr_phys_segs > queue_max_segments(q)) if (req->nr_phys_segments + nr_phys_segs > blk_rq_get_max_segments(req))
goto no_merge; goto no_merge;
if (blk_integrity_merge_bio(q, req, bio) == false) if (blk_integrity_merge_bio(q, req, bio) == false)
...@@ -606,7 +613,7 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req, ...@@ -606,7 +613,7 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
total_phys_segments--; total_phys_segments--;
} }
if (total_phys_segments > queue_max_segments(q)) if (total_phys_segments > blk_rq_get_max_segments(req))
return 0; return 0;
if (blk_integrity_merge_rq(q, req, next) == false) if (blk_integrity_merge_rq(q, req, next) == false)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册