Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 76d8137a authored by Ming Lei's avatar Ming Lei Committed by Jens Axboe
Browse files

blk-merge: recaculate segment if it isn't less than max segments



The problem is introduced by commit 764f612c(blk-merge:
don't compute bi_phys_segments from bi_vcnt for cloned bio),
and merge is needed if number of current segment isn't less than
max segments.

Strictly speaking, bio->bi_vcnt shouldn't be used here since
it may not be accurate in cases of both cloned bio or bio cloned
from, but bio_segments() is a bit expensive, and bi_vcnt is still
the biggest number, so the approach should work.

Signed-off-by: default avatarMing Lei <tom.leiming@gmail.com>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent 432f16e6
Loading
Loading
Loading
Loading
+3 −2
Original line number Original line Diff line number Diff line
@@ -99,16 +99,17 @@ void blk_recount_segments(struct request_queue *q, struct bio *bio)
{
{
	bool no_sg_merge = !!test_bit(QUEUE_FLAG_NO_SG_MERGE,
	bool no_sg_merge = !!test_bit(QUEUE_FLAG_NO_SG_MERGE,
			&q->queue_flags);
			&q->queue_flags);
	bool merge_not_need = bio->bi_vcnt < queue_max_segments(q);


	if (no_sg_merge && !bio_flagged(bio, BIO_CLONED) &&
	if (no_sg_merge && !bio_flagged(bio, BIO_CLONED) &&
			bio->bi_vcnt < queue_max_segments(q))
			merge_not_need)
		bio->bi_phys_segments = bio->bi_vcnt;
		bio->bi_phys_segments = bio->bi_vcnt;
	else {
	else {
		struct bio *nxt = bio->bi_next;
		struct bio *nxt = bio->bi_next;


		bio->bi_next = NULL;
		bio->bi_next = NULL;
		bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio,
		bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio,
				no_sg_merge);
				no_sg_merge && merge_not_need);
		bio->bi_next = nxt;
		bio->bi_next = nxt;
	}
	}