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);