Skip to content

Commit 2705dfb

Browse files
Ming Leiaxboe
authored andcommitted
block: fix discard request merge
ll_new_hw_segment() is reached only in case of single range discard merge, and we don't have max discard segment size limit actually, so it is wrong to run the following check: if (req->nr_phys_segments + nr_phys_segs > blk_rq_get_max_segments(req)) it may be always false since req->nr_phys_segments is initialized as one, and bio's segment count is still 1, blk_rq_get_max_segments(reg) is 1 too. Fix the issue by not doing the check and bypassing the calculation of discard request's nr_phys_segments. Based on analysis from Wang Shanker. Cc: Christoph Hellwig <[email protected]> Reported-by: Wang Shanker <[email protected]> Signed-off-by: Ming Lei <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent c06bc5a commit 2705dfb

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

block/blk-merge.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -559,10 +559,14 @@ static inline unsigned int blk_rq_get_max_segments(struct request *rq)
559559
static inline int ll_new_hw_segment(struct request *req, struct bio *bio,
560560
unsigned int nr_phys_segs)
561561
{
562-
if (req->nr_phys_segments + nr_phys_segs > blk_rq_get_max_segments(req))
562+
if (blk_integrity_merge_bio(req->q, req, bio) == false)
563563
goto no_merge;
564564

565-
if (blk_integrity_merge_bio(req->q, req, bio) == false)
565+
/* discard request merge won't add new segment */
566+
if (req_op(req) == REQ_OP_DISCARD)
567+
return 1;
568+
569+
if (req->nr_phys_segments + nr_phys_segs > blk_rq_get_max_segments(req))
566570
goto no_merge;
567571

568572
/*

0 commit comments

Comments
 (0)