diff --git a/block/blk-merge.c b/block/blk-merge.c index 21e87a714a73..af122efeb28d 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -622,6 +622,8 @@ static inline int ll_new_hw_segment(struct request_queue *q, struct bio *bio) { int nr_phys_segs = bio_phys_segments(q, bio); + unsigned int seg_size = + req->biotail->bi_seg_back_size + bio->bi_seg_front_size; if (req->nr_phys_segments + nr_phys_segs > queue_max_segments(q)) goto no_merge; @@ -629,11 +631,15 @@ static inline int ll_new_hw_segment(struct request_queue *q, if (blk_integrity_merge_bio(q, req, bio) == false) goto no_merge; - /* - * This will form the start of a new hw segment. Bump both - * counters. - */ - req->nr_phys_segments += nr_phys_segs; + if (blk_phys_contig_segment(q, req->biotail, bio)) { + if (nr_phys_segs) + req->nr_phys_segments += nr_phys_segs - 1; + if (nr_phys_segs == 1) + bio->bi_seg_back_size = seg_size; + if (req->nr_phys_segments == 1) + req->bio->bi_seg_front_size = seg_size; + } else + req->nr_phys_segments += nr_phys_segs; return 1; no_merge: -- 2.20.1