aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/bio.c53
-rw-r--r--block/blk-map.c137
-rw-r--r--include/linux/bio.h4
3 files changed, 14 insertions, 180 deletions
diff --git a/block/bio.c b/block/bio.c
index 54da51ed43de..879921e6b049 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1102,7 +1102,7 @@ static int __bio_copy_iov(struct bio *bio, const struct sg_iovec *iov, int iov_c
1102 * bio_uncopy_user - finish previously mapped bio 1102 * bio_uncopy_user - finish previously mapped bio
1103 * @bio: bio being terminated 1103 * @bio: bio being terminated
1104 * 1104 *
1105 * Free pages allocated from bio_copy_user() and write back data 1105 * Free pages allocated from bio_copy_user_iov() and write back data
1106 * to user space in case of a read. 1106 * to user space in case of a read.
1107 */ 1107 */
1108int bio_uncopy_user(struct bio *bio) 1108int bio_uncopy_user(struct bio *bio)
@@ -1256,32 +1256,6 @@ out_bmd:
1256 return ERR_PTR(ret); 1256 return ERR_PTR(ret);
1257} 1257}
1258 1258
1259/**
1260 * bio_copy_user - copy user data to bio
1261 * @q: destination block queue
1262 * @map_data: pointer to the rq_map_data holding pages (if necessary)
1263 * @uaddr: start of user address
1264 * @len: length in bytes
1265 * @write_to_vm: bool indicating writing to pages or not
1266 * @gfp_mask: memory allocation flags
1267 *
1268 * Prepares and returns a bio for indirect user io, bouncing data
1269 * to/from kernel pages as necessary. Must be paired with
1270 * call bio_uncopy_user() on io completion.
1271 */
1272struct bio *bio_copy_user(struct request_queue *q, struct rq_map_data *map_data,
1273 unsigned long uaddr, unsigned int len,
1274 int write_to_vm, gfp_t gfp_mask)
1275{
1276 struct sg_iovec iov;
1277
1278 iov.iov_base = (void __user *)uaddr;
1279 iov.iov_len = len;
1280
1281 return bio_copy_user_iov(q, map_data, &iov, 1, write_to_vm, gfp_mask);
1282}
1283EXPORT_SYMBOL(bio_copy_user);
1284
1285static struct bio *__bio_map_user_iov(struct request_queue *q, 1259static struct bio *__bio_map_user_iov(struct request_queue *q,
1286 struct block_device *bdev, 1260 struct block_device *bdev,
1287 const struct sg_iovec *iov, int iov_count, 1261 const struct sg_iovec *iov, int iov_count,
@@ -1395,31 +1369,6 @@ static struct bio *__bio_map_user_iov(struct request_queue *q,
1395} 1369}
1396 1370
1397/** 1371/**
1398 * bio_map_user - map user address into bio
1399 * @q: the struct request_queue for the bio
1400 * @bdev: destination block device
1401 * @uaddr: start of user address
1402 * @len: length in bytes
1403 * @write_to_vm: bool indicating writing to pages or not
1404 * @gfp_mask: memory allocation flags
1405 *
1406 * Map the user space address into a bio suitable for io to a block
1407 * device. Returns an error pointer in case of error.
1408 */
1409struct bio *bio_map_user(struct request_queue *q, struct block_device *bdev,
1410 unsigned long uaddr, unsigned int len, int write_to_vm,
1411 gfp_t gfp_mask)
1412{
1413 struct sg_iovec iov;
1414
1415 iov.iov_base = (void __user *)uaddr;
1416 iov.iov_len = len;
1417
1418 return bio_map_user_iov(q, bdev, &iov, 1, write_to_vm, gfp_mask);
1419}
1420EXPORT_SYMBOL(bio_map_user);
1421
1422/**
1423 * bio_map_user_iov - map user sg_iovec table into bio 1372 * bio_map_user_iov - map user sg_iovec table into bio
1424 * @q: the struct request_queue for the bio 1373 * @q: the struct request_queue for the bio
1425 * @bdev: destination block device 1374 * @bdev: destination block device
diff --git a/block/blk-map.c b/block/blk-map.c
index f890d4345b0c..152a5fe5d85e 100644
--- a/block/blk-map.c
+++ b/block/blk-map.c
@@ -39,130 +39,6 @@ static int __blk_rq_unmap_user(struct bio *bio)
39 return ret; 39 return ret;
40} 40}
41 41
42static int __blk_rq_map_user(struct request_queue *q, struct request *rq,
43 struct rq_map_data *map_data, void __user *ubuf,
44 unsigned int len, gfp_t gfp_mask)
45{
46 unsigned long uaddr;
47 struct bio *bio, *orig_bio;
48 int reading, ret;
49
50 reading = rq_data_dir(rq) == READ;
51
52 /*
53 * if alignment requirement is satisfied, map in user pages for
54 * direct dma. else, set up kernel bounce buffers
55 */
56 uaddr = (unsigned long) ubuf;
57 if (blk_rq_aligned(q, uaddr, len) && !map_data)
58 bio = bio_map_user(q, NULL, uaddr, len, reading, gfp_mask);
59 else
60 bio = bio_copy_user(q, map_data, uaddr, len, reading, gfp_mask);
61
62 if (IS_ERR(bio))
63 return PTR_ERR(bio);
64
65 if (map_data && map_data->null_mapped)
66 bio->bi_flags |= (1 << BIO_NULL_MAPPED);
67
68 orig_bio = bio;
69 blk_queue_bounce(q, &bio);
70
71 /*
72 * We link the bounce buffer in and could have to traverse it
73 * later so we have to get a ref to prevent it from being freed
74 */
75 bio_get(bio);
76
77 ret = blk_rq_append_bio(q, rq, bio);
78 if (!ret)
79 return bio->bi_iter.bi_size;
80
81 /* if it was boucned we must call the end io function */
82 bio_endio(bio, 0);
83 __blk_rq_unmap_user(orig_bio);
84 bio_put(bio);
85 return ret;
86}
87
88/**
89 * blk_rq_map_user - map user data to a request, for REQ_TYPE_BLOCK_PC usage
90 * @q: request queue where request should be inserted
91 * @rq: request structure to fill
92 * @map_data: pointer to the rq_map_data holding pages (if necessary)
93 * @ubuf: the user buffer
94 * @len: length of user data
95 * @gfp_mask: memory allocation flags
96 *
97 * Description:
98 * Data will be mapped directly for zero copy I/O, if possible. Otherwise
99 * a kernel bounce buffer is used.
100 *
101 * A matching blk_rq_unmap_user() must be issued at the end of I/O, while
102 * still in process context.
103 *
104 * Note: The mapped bio may need to be bounced through blk_queue_bounce()
105 * before being submitted to the device, as pages mapped may be out of
106 * reach. It's the callers responsibility to make sure this happens. The
107 * original bio must be passed back in to blk_rq_unmap_user() for proper
108 * unmapping.
109 */
110int blk_rq_map_user(struct request_queue *q, struct request *rq,
111 struct rq_map_data *map_data, void __user *ubuf,
112 unsigned long len, gfp_t gfp_mask)
113{
114 unsigned long bytes_read = 0;
115 struct bio *bio = NULL;
116 int ret;
117
118 if (len > (queue_max_hw_sectors(q) << 9))
119 return -EINVAL;
120 if (!len)
121 return -EINVAL;
122
123 if (!ubuf && (!map_data || !map_data->null_mapped))
124 return -EINVAL;
125
126 while (bytes_read != len) {
127 unsigned long map_len, end, start;
128
129 map_len = min_t(unsigned long, len - bytes_read, BIO_MAX_SIZE);
130 end = ((unsigned long)ubuf + map_len + PAGE_SIZE - 1)
131 >> PAGE_SHIFT;
132 start = (unsigned long)ubuf >> PAGE_SHIFT;
133
134 /*
135 * A bad offset could cause us to require BIO_MAX_PAGES + 1
136 * pages. If this happens we just lower the requested
137 * mapping len by a page so that we can fit
138 */
139 if (end - start > BIO_MAX_PAGES)
140 map_len -= PAGE_SIZE;
141
142 ret = __blk_rq_map_user(q, rq, map_data, ubuf, map_len,
143 gfp_mask);
144 if (ret < 0)
145 goto unmap_rq;
146 if (!bio)
147 bio = rq->bio;
148 bytes_read += ret;
149 ubuf += ret;
150
151 if (map_data)
152 map_data->offset += ret;
153 }
154
155 if (!bio_flagged(bio, BIO_USER_MAPPED))
156 rq->cmd_flags |= REQ_COPY_USER;
157
158 return 0;
159unmap_rq:
160 blk_rq_unmap_user(bio);
161 rq->bio = NULL;
162 return ret;
163}
164EXPORT_SYMBOL(blk_rq_map_user);
165
166/** 42/**
167 * blk_rq_map_user_iov - map user data to a request, for REQ_TYPE_BLOCK_PC usage 43 * blk_rq_map_user_iov - map user data to a request, for REQ_TYPE_BLOCK_PC usage
168 * @q: request queue where request should be inserted 44 * @q: request queue where request should be inserted
@@ -241,6 +117,19 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
241} 117}
242EXPORT_SYMBOL(blk_rq_map_user_iov); 118EXPORT_SYMBOL(blk_rq_map_user_iov);
243 119
120int blk_rq_map_user(struct request_queue *q, struct request *rq,
121 struct rq_map_data *map_data, void __user *ubuf,
122 unsigned long len, gfp_t gfp_mask)
123{
124 struct sg_iovec iov;
125
126 iov.iov_base = (void __user *)ubuf;
127 iov.iov_len = len;
128
129 return blk_rq_map_user_iov(q, rq, map_data, &iov, 1, len, gfp_mask);
130}
131EXPORT_SYMBOL(blk_rq_map_user);
132
244/** 133/**
245 * blk_rq_unmap_user - unmap a request with user data 134 * blk_rq_unmap_user - unmap a request with user data
246 * @bio: start of bio list 135 * @bio: start of bio list
diff --git a/include/linux/bio.h b/include/linux/bio.h
index efead0b532c4..d0d6735d61da 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -428,8 +428,6 @@ extern int bio_add_page(struct bio *, struct page *, unsigned int,unsigned int);
428extern int bio_add_pc_page(struct request_queue *, struct bio *, struct page *, 428extern int bio_add_pc_page(struct request_queue *, struct bio *, struct page *,
429 unsigned int, unsigned int); 429 unsigned int, unsigned int);
430extern int bio_get_nr_vecs(struct block_device *); 430extern int bio_get_nr_vecs(struct block_device *);
431extern struct bio *bio_map_user(struct request_queue *, struct block_device *,
432 unsigned long, unsigned int, int, gfp_t);
433struct sg_iovec; 431struct sg_iovec;
434struct rq_map_data; 432struct rq_map_data;
435extern struct bio *bio_map_user_iov(struct request_queue *, 433extern struct bio *bio_map_user_iov(struct request_queue *,
@@ -462,8 +460,6 @@ static inline void bio_flush_dcache_pages(struct bio *bi)
462extern void bio_copy_data(struct bio *dst, struct bio *src); 460extern void bio_copy_data(struct bio *dst, struct bio *src);
463extern int bio_alloc_pages(struct bio *bio, gfp_t gfp); 461extern int bio_alloc_pages(struct bio *bio, gfp_t gfp);
464 462
465extern struct bio *bio_copy_user(struct request_queue *, struct rq_map_data *,
466 unsigned long, unsigned int, int, gfp_t);
467extern struct bio *bio_copy_user_iov(struct request_queue *, 463extern struct bio *bio_copy_user_iov(struct request_queue *,
468 struct rq_map_data *, 464 struct rq_map_data *,
469 const struct sg_iovec *, 465 const struct sg_iovec *,