Commit 85b9f66a41eb8ee3f1dfc95707412705463cdd97
Committed by
Jens Axboe
1 parent
963ab9e5da
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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
block/blk-merge.c
... | ... | @@ -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 |