blk-map.c (9d66a875ecc7d6dd414121e4508340d6c08f51b0) | blk-map.c (69e0927b3774563c19b5fb32e91d75edc147fb62) |
---|---|
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Functions related to mapping data to requests 4 */ 5#include <linux/kernel.h> 6#include <linux/sched/task_stack.h> 7#include <linux/module.h> 8#include <linux/bio.h> 9#include <linux/blkdev.h> 10#include <linux/uio.h> 11 12#include "blk.h" 13 14/* | 1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Functions related to mapping data to requests 4 */ 5#include <linux/kernel.h> 6#include <linux/sched/task_stack.h> 7#include <linux/module.h> 8#include <linux/bio.h> 9#include <linux/blkdev.h> 10#include <linux/uio.h> 11 12#include "blk.h" 13 14/* |
15 * Append a bio to a passthrough request. Only works if the bio can be merged 16 * into the request based on the driver constraints. | 15 * Append a bio to a passthrough request. Only works can be merged into 16 * the request based on the driver constraints. |
17 */ | 17 */ |
18int blk_rq_append_bio(struct request *rq, struct bio **bio) | 18int blk_rq_append_bio(struct request *rq, struct bio *bio) |
19{ | 19{ |
20 struct bio *orig_bio = *bio; | 20 blk_queue_bounce(rq->q, &bio); |
21 | 21 |
22 blk_queue_bounce(rq->q, bio); 23 | |
24 if (!rq->bio) { | 22 if (!rq->bio) { |
25 blk_rq_bio_prep(rq->q, rq, *bio); | 23 blk_rq_bio_prep(rq->q, rq, bio); |
26 } else { | 24 } else { |
27 if (!ll_back_merge_fn(rq->q, rq, *bio)) { 28 if (orig_bio != *bio) { 29 bio_put(*bio); 30 *bio = orig_bio; 31 } | 25 if (!ll_back_merge_fn(rq->q, rq, bio)) |
32 return -EINVAL; | 26 return -EINVAL; |
33 } | |
34 | 27 |
35 rq->biotail->bi_next = *bio; 36 rq->biotail = *bio; 37 rq->__data_len += (*bio)->bi_iter.bi_size; | 28 rq->biotail->bi_next = bio; 29 rq->biotail = bio; 30 rq->__data_len += bio->bi_iter.bi_size; |
38 } 39 40 return 0; 41} 42EXPORT_SYMBOL(blk_rq_append_bio); 43 44static int __blk_rq_unmap_user(struct bio *bio) 45{ --- 29 unchanged lines hidden (view full) --- 75 bio->bi_opf |= req_op(rq); 76 77 orig_bio = bio; 78 79 /* 80 * We link the bounce buffer in and could have to traverse it 81 * later so we have to get a ref to prevent it from being freed 82 */ | 31 } 32 33 return 0; 34} 35EXPORT_SYMBOL(blk_rq_append_bio); 36 37static int __blk_rq_unmap_user(struct bio *bio) 38{ --- 29 unchanged lines hidden (view full) --- 68 bio->bi_opf |= req_op(rq); 69 70 orig_bio = bio; 71 72 /* 73 * We link the bounce buffer in and could have to traverse it 74 * later so we have to get a ref to prevent it from being freed 75 */ |
83 ret = blk_rq_append_bio(rq, &bio); | 76 ret = blk_rq_append_bio(rq, bio); 77 bio_get(bio); |
84 if (ret) { | 78 if (ret) { |
79 bio_endio(bio); |
|
85 __blk_rq_unmap_user(orig_bio); | 80 __blk_rq_unmap_user(orig_bio); |
81 bio_put(bio); |
|
86 return ret; 87 } | 82 return ret; 83 } |
88 bio_get(bio); | |
89 90 return 0; 91} 92 93/** 94 * blk_rq_map_user_iov - map user data to a request, for passthrough requests 95 * @q: request queue where request should be inserted 96 * @rq: request to map data to --- 17 unchanged lines hidden (view full) --- 114int blk_rq_map_user_iov(struct request_queue *q, struct request *rq, 115 struct rq_map_data *map_data, 116 const struct iov_iter *iter, gfp_t gfp_mask) 117{ 118 bool copy = false; 119 unsigned long align = q->dma_pad_mask | queue_dma_alignment(q); 120 struct bio *bio = NULL; 121 struct iov_iter i; | 84 85 return 0; 86} 87 88/** 89 * blk_rq_map_user_iov - map user data to a request, for passthrough requests 90 * @q: request queue where request should be inserted 91 * @rq: request to map data to --- 17 unchanged lines hidden (view full) --- 109int blk_rq_map_user_iov(struct request_queue *q, struct request *rq, 110 struct rq_map_data *map_data, 111 const struct iov_iter *iter, gfp_t gfp_mask) 112{ 113 bool copy = false; 114 unsigned long align = q->dma_pad_mask | queue_dma_alignment(q); 115 struct bio *bio = NULL; 116 struct iov_iter i; |
122 int ret; | 117 int ret = -EINVAL; |
123 124 if (!iter_is_iovec(iter)) 125 goto fail; 126 127 if (map_data) 128 copy = true; 129 else if (iov_iter_alignment(iter) & align) 130 copy = true; --- 12 unchanged lines hidden (view full) --- 143 if (!bio_flagged(bio, BIO_USER_MAPPED)) 144 rq->rq_flags |= RQF_COPY_USER; 145 return 0; 146 147unmap_rq: 148 __blk_rq_unmap_user(bio); 149fail: 150 rq->bio = NULL; | 118 119 if (!iter_is_iovec(iter)) 120 goto fail; 121 122 if (map_data) 123 copy = true; 124 else if (iov_iter_alignment(iter) & align) 125 copy = true; --- 12 unchanged lines hidden (view full) --- 138 if (!bio_flagged(bio, BIO_USER_MAPPED)) 139 rq->rq_flags |= RQF_COPY_USER; 140 return 0; 141 142unmap_rq: 143 __blk_rq_unmap_user(bio); 144fail: 145 rq->bio = NULL; |
151 return -EINVAL; | 146 return ret; |
152} 153EXPORT_SYMBOL(blk_rq_map_user_iov); 154 155int blk_rq_map_user(struct request_queue *q, struct request *rq, 156 struct rq_map_data *map_data, void __user *ubuf, 157 unsigned long len, gfp_t gfp_mask) 158{ 159 struct iovec iov; --- 53 unchanged lines hidden (view full) --- 213 * buffers. 214 */ 215int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf, 216 unsigned int len, gfp_t gfp_mask) 217{ 218 int reading = rq_data_dir(rq) == READ; 219 unsigned long addr = (unsigned long) kbuf; 220 int do_copy = 0; | 147} 148EXPORT_SYMBOL(blk_rq_map_user_iov); 149 150int blk_rq_map_user(struct request_queue *q, struct request *rq, 151 struct rq_map_data *map_data, void __user *ubuf, 152 unsigned long len, gfp_t gfp_mask) 153{ 154 struct iovec iov; --- 53 unchanged lines hidden (view full) --- 208 * buffers. 209 */ 210int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf, 211 unsigned int len, gfp_t gfp_mask) 212{ 213 int reading = rq_data_dir(rq) == READ; 214 unsigned long addr = (unsigned long) kbuf; 215 int do_copy = 0; |
221 struct bio *bio, *orig_bio; | 216 struct bio *bio; |
222 int ret; 223 224 if (len > (queue_max_hw_sectors(q) << 9)) 225 return -EINVAL; 226 if (!len || !kbuf) 227 return -EINVAL; 228 229 do_copy = !blk_rq_aligned(q, addr, len) || object_is_on_stack(kbuf); --- 6 unchanged lines hidden (view full) --- 236 return PTR_ERR(bio); 237 238 bio->bi_opf &= ~REQ_OP_MASK; 239 bio->bi_opf |= req_op(rq); 240 241 if (do_copy) 242 rq->rq_flags |= RQF_COPY_USER; 243 | 217 int ret; 218 219 if (len > (queue_max_hw_sectors(q) << 9)) 220 return -EINVAL; 221 if (!len || !kbuf) 222 return -EINVAL; 223 224 do_copy = !blk_rq_aligned(q, addr, len) || object_is_on_stack(kbuf); --- 6 unchanged lines hidden (view full) --- 231 return PTR_ERR(bio); 232 233 bio->bi_opf &= ~REQ_OP_MASK; 234 bio->bi_opf |= req_op(rq); 235 236 if (do_copy) 237 rq->rq_flags |= RQF_COPY_USER; 238 |
244 orig_bio = bio; 245 ret = blk_rq_append_bio(rq, &bio); | 239 ret = blk_rq_append_bio(rq, bio); |
246 if (unlikely(ret)) { 247 /* request is too big */ | 240 if (unlikely(ret)) { 241 /* request is too big */ |
248 bio_put(orig_bio); | 242 bio_put(bio); |
249 return ret; 250 } 251 252 return 0; 253} 254EXPORT_SYMBOL(blk_rq_map_kern); | 243 return ret; 244 } 245 246 return 0; 247} 248EXPORT_SYMBOL(blk_rq_map_kern); |