Prepare for adding an additional call to bio_chain_nr_segments(). Cc: Christoph Hellwig <hch@xxxxxx> Cc: Ming Lei <ming.lei@xxxxxxxxxx> Cc: Damien Le Moal <damien.lemoal@xxxxxxxxxxxxxxxxxx> Cc: Johannes Thumshirn <johannes.thumshirn@xxxxxxx> Signed-off-by: Bart Van Assche <bvanassche@xxxxxxx> --- block/blk-merge.c | 26 ++++++++++++++++---------- block/blk.h | 2 ++ 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/block/blk-merge.c b/block/blk-merge.c index 65e75efa9bd3..d6f8552ef209 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -409,22 +409,22 @@ struct bio *bio_split_to_limits(struct bio *bio) } EXPORT_SYMBOL(bio_split_to_limits); -unsigned int blk_recalc_rq_segments(struct request *rq) +/* Calculate the number of DMA segments in a bio chain. */ +unsigned int bio_chain_nr_segments(struct bio *bio, + const struct queue_limits *lim) { unsigned int nr_phys_segs = 0; unsigned int bytes = 0; - struct req_iterator iter; + struct bvec_iter iter; struct bio_vec bv; - if (!rq->bio) + if (!bio) return 0; - switch (bio_op(rq->bio)) { + switch (bio_op(bio)) { case REQ_OP_DISCARD: case REQ_OP_SECURE_ERASE: - if (queue_max_discard_segments(rq->q) > 1) { - struct bio *bio = rq->bio; - + if (lim->max_discard_segments > 1) { for_each_bio(bio) nr_phys_segs++; return nr_phys_segs; @@ -436,12 +436,18 @@ unsigned int blk_recalc_rq_segments(struct request *rq) break; } - rq_for_each_bvec(bv, rq, iter) - bvec_split_segs(&rq->q->limits, &bv, &nr_phys_segs, &bytes, - UINT_MAX, UINT_MAX); + for_each_bio(bio) + bio_for_each_bvec(bv, bio, iter) + bvec_split_segs(lim, &bv, &nr_phys_segs, &bytes, + UINT_MAX, UINT_MAX); return nr_phys_segs; } +unsigned int blk_recalc_rq_segments(struct request *rq) +{ + return bio_chain_nr_segments(rq->bio, &rq->q->limits); +} + static inline struct scatterlist *blk_next_sg(struct scatterlist **sg, struct scatterlist *sglist) { diff --git a/block/blk.h b/block/blk.h index d65d96994a94..ea15b1a4c2b7 100644 --- a/block/blk.h +++ b/block/blk.h @@ -330,6 +330,8 @@ int ll_back_merge_fn(struct request *req, struct bio *bio, unsigned int nr_segs); bool blk_attempt_req_merge(struct request_queue *q, struct request *rq, struct request *next); +unsigned int bio_chain_nr_segments(struct bio *bio, + const struct queue_limits *lim); unsigned int blk_recalc_rq_segments(struct request *rq); void blk_rq_set_mixed_merge(struct request *rq); bool blk_rq_merge_ok(struct request *rq, struct bio *bio);