Commit 85b9f66a41eb8ee3f1dfc95707412705463cdd97

Authored by Asias He
Committed by Jens Axboe
1 parent 963ab9e5da

block: Add blk_bio_map_sg() helper

Add a helper to map a bio to a scatterlist, modelled after
blk_rq_map_sg.

This helper is useful for any driver that wants to create
a scatterlist from its ->make_request_fn method.

Changes in v2:
 - Use __blk_segment_map_sg to avoid duplicated code
 - Add cocbook style function comment

Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Tejun Heo <tj@kernel.org>
Cc: Shaohua Li <shli@kernel.org>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: kvm@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: virtualization@lists.linux-foundation.org
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Minchan Kim <minchan.kim@gmail.com>
Signed-off-by: Asias He <asias@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

Showing 2 changed files with 39 additions and 0 deletions Side-by-side Diff

... ... @@ -209,6 +209,43 @@
209 209 }
210 210 EXPORT_SYMBOL(blk_rq_map_sg);
211 211  
  212 +/**
  213 + * blk_bio_map_sg - map a bio to a scatterlist
  214 + * @q: request_queue in question
  215 + * @bio: bio being mapped
  216 + * @sglist: scatterlist being mapped
  217 + *
  218 + * Note:
  219 + * Caller must make sure sg can hold bio->bi_phys_segments entries
  220 + *
  221 + * Will return the number of sg entries setup
  222 + */
  223 +int blk_bio_map_sg(struct request_queue *q, struct bio *bio,
  224 + struct scatterlist *sglist)
  225 +{
  226 + struct bio_vec *bvec, *bvprv;
  227 + struct scatterlist *sg;
  228 + int nsegs, cluster;
  229 + unsigned long i;
  230 +
  231 + nsegs = 0;
  232 + cluster = blk_queue_cluster(q);
  233 +
  234 + bvprv = NULL;
  235 + sg = NULL;
  236 + bio_for_each_segment(bvec, bio, i) {
  237 + __blk_segment_map_sg(q, bvec, sglist, &bvprv, &sg,
  238 + &nsegs, &cluster);
  239 + } /* segments in bio */
  240 +
  241 + if (sg)
  242 + sg_mark_end(sg);
  243 +
  244 + BUG_ON(bio->bi_phys_segments && nsegs > bio->bi_phys_segments);
  245 + return nsegs;
  246 +}
  247 +EXPORT_SYMBOL(blk_bio_map_sg);
  248 +
212 249 static inline int ll_new_hw_segment(struct request_queue *q,
213 250 struct request *req,
214 251 struct bio *bio)
include/linux/blkdev.h
... ... @@ -894,6 +894,8 @@
894 894 extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev);
895 895  
896 896 extern int blk_rq_map_sg(struct request_queue *, struct request *, struct scatterlist *);
  897 +extern int blk_bio_map_sg(struct request_queue *q, struct bio *bio,
  898 + struct scatterlist *sglist);
897 899 extern void blk_dump_rq_flags(struct request *, char *);
898 900 extern long nr_blockdev_pages(void);
899 901