mirror of
https://github.com/torvalds/linux
synced 2024-09-06 18:01:05 +00:00
block: blk-merge: fix blk_recount_segments()
For cloned bio, bio->bi_vcnt can't be used at all, and we have resort to bio_segments() to figure out how many segment there are in the bio. Signed-off-by: Ming Lei <tom.leiming@gmail.com> Signed-off-by: Jens Axboe <axboe@fb.com>
This commit is contained in:
parent
92697dc947
commit
7f60dcaaf9
|
@ -97,19 +97,22 @@ void blk_recalc_rq_segments(struct request *rq)
|
|||
|
||||
void blk_recount_segments(struct request_queue *q, struct bio *bio)
|
||||
{
|
||||
bool no_sg_merge = !!test_bit(QUEUE_FLAG_NO_SG_MERGE,
|
||||
&q->queue_flags);
|
||||
bool merge_not_need = bio->bi_vcnt < queue_max_segments(q);
|
||||
unsigned short seg_cnt;
|
||||
|
||||
if (no_sg_merge && !bio_flagged(bio, BIO_CLONED) &&
|
||||
merge_not_need)
|
||||
bio->bi_phys_segments = bio->bi_vcnt;
|
||||
/* estimate segment number by bi_vcnt for non-cloned bio */
|
||||
if (bio_flagged(bio, BIO_CLONED))
|
||||
seg_cnt = bio_segments(bio);
|
||||
else
|
||||
seg_cnt = bio->bi_vcnt;
|
||||
|
||||
if (test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags) &&
|
||||
(seg_cnt < queue_max_segments(q)))
|
||||
bio->bi_phys_segments = seg_cnt;
|
||||
else {
|
||||
struct bio *nxt = bio->bi_next;
|
||||
|
||||
bio->bi_next = NULL;
|
||||
bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio,
|
||||
no_sg_merge && merge_not_need);
|
||||
bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, false);
|
||||
bio->bi_next = nxt;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue