aboutsummaryrefslogtreecommitdiffstats
path: root/block/blk-map.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/blk-map.c')
-rw-r--r--block/blk-map.c38
1 files changed, 19 insertions, 19 deletions
diff --git a/block/blk-map.c b/block/blk-map.c
index 152a5fe5d85e..30e6bb871c5c 100644
--- a/block/blk-map.c
+++ b/block/blk-map.c
@@ -5,7 +5,7 @@
5#include <linux/module.h> 5#include <linux/module.h>
6#include <linux/bio.h> 6#include <linux/bio.h>
7#include <linux/blkdev.h> 7#include <linux/blkdev.h>
8#include <scsi/sg.h> /* for struct sg_iovec */ 8#include <linux/uio.h>
9 9
10#include "blk.h" 10#include "blk.h"
11 11
@@ -44,9 +44,7 @@ static int __blk_rq_unmap_user(struct bio *bio)
44 * @q: request queue where request should be inserted 44 * @q: request queue where request should be inserted
45 * @rq: request to map data to 45 * @rq: request to map data to
46 * @map_data: pointer to the rq_map_data holding pages (if necessary) 46 * @map_data: pointer to the rq_map_data holding pages (if necessary)
47 * @iov: pointer to the iovec 47 * @iter: iovec iterator
48 * @iov_count: number of elements in the iovec
49 * @len: I/O byte count
50 * @gfp_mask: memory allocation flags 48 * @gfp_mask: memory allocation flags
51 * 49 *
52 * Description: 50 * Description:
@@ -63,20 +61,21 @@ static int __blk_rq_unmap_user(struct bio *bio)
63 * unmapping. 61 * unmapping.
64 */ 62 */
65int blk_rq_map_user_iov(struct request_queue *q, struct request *rq, 63int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
66 struct rq_map_data *map_data, const struct sg_iovec *iov, 64 struct rq_map_data *map_data,
67 int iov_count, unsigned int len, gfp_t gfp_mask) 65 const struct iov_iter *iter, gfp_t gfp_mask)
68{ 66{
69 struct bio *bio; 67 struct bio *bio;
70 int i, read = rq_data_dir(rq) == READ;
71 int unaligned = 0; 68 int unaligned = 0;
69 struct iov_iter i;
70 struct iovec iov;
72 71
73 if (!iov || iov_count <= 0) 72 if (!iter || !iter->count)
74 return -EINVAL; 73 return -EINVAL;
75 74
76 for (i = 0; i < iov_count; i++) { 75 iov_for_each(iov, i, *iter) {
77 unsigned long uaddr = (unsigned long)iov[i].iov_base; 76 unsigned long uaddr = (unsigned long) iov.iov_base;
78 77
79 if (!iov[i].iov_len) 78 if (!iov.iov_len)
80 return -EINVAL; 79 return -EINVAL;
81 80
82 /* 81 /*
@@ -86,16 +85,15 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
86 unaligned = 1; 85 unaligned = 1;
87 } 86 }
88 87
89 if (unaligned || (q->dma_pad_mask & len) || map_data) 88 if (unaligned || (q->dma_pad_mask & iter->count) || map_data)
90 bio = bio_copy_user_iov(q, map_data, iov, iov_count, read, 89 bio = bio_copy_user_iov(q, map_data, iter, gfp_mask);
91 gfp_mask);
92 else 90 else
93 bio = bio_map_user_iov(q, NULL, iov, iov_count, read, gfp_mask); 91 bio = bio_map_user_iov(q, NULL, iter, gfp_mask);
94 92
95 if (IS_ERR(bio)) 93 if (IS_ERR(bio))
96 return PTR_ERR(bio); 94 return PTR_ERR(bio);
97 95
98 if (bio->bi_iter.bi_size != len) { 96 if (bio->bi_iter.bi_size != iter->count) {
99 /* 97 /*
100 * Grab an extra reference to this bio, as bio_unmap_user() 98 * Grab an extra reference to this bio, as bio_unmap_user()
101 * expects to be able to drop it twice as it happens on the 99 * expects to be able to drop it twice as it happens on the
@@ -121,12 +119,14 @@ int blk_rq_map_user(struct request_queue *q, struct request *rq,
121 struct rq_map_data *map_data, void __user *ubuf, 119 struct rq_map_data *map_data, void __user *ubuf,
122 unsigned long len, gfp_t gfp_mask) 120 unsigned long len, gfp_t gfp_mask)
123{ 121{
124 struct sg_iovec iov; 122 struct iovec iov;
123 struct iov_iter i;
125 124
126 iov.iov_base = (void __user *)ubuf; 125 iov.iov_base = ubuf;
127 iov.iov_len = len; 126 iov.iov_len = len;
127 iov_iter_init(&i, rq_data_dir(rq), &iov, 1, len);
128 128
129 return blk_rq_map_user_iov(q, rq, map_data, &iov, 1, len, gfp_mask); 129 return blk_rq_map_user_iov(q, rq, map_data, &i, gfp_mask);
130} 130}
131EXPORT_SYMBOL(blk_rq_map_user); 131EXPORT_SYMBOL(blk_rq_map_user);
132 132