]> git.karo-electronics.de Git - karo-tx-linux.git/blob - fs/iov-iter.c
iov_iter: add bvec support
[karo-tx-linux.git] / fs / iov-iter.c
1 #include <linux/module.h>
2 #include <linux/fs.h>
3 #include <linux/uaccess.h>
4 #include <linux/uio.h>
5 #include <linux/hardirq.h>
6 #include <linux/highmem.h>
7 #include <linux/pagemap.h>
8 #include <linux/bio.h>
9
10 static size_t __iovec_copy_to_user(char *vaddr, const struct iovec *iov,
11                                    size_t base, size_t bytes, int atomic)
12 {
13         size_t copied = 0, left = 0;
14
15         while (bytes) {
16                 char __user *buf = iov->iov_base + base;
17                 int copy = min(bytes, iov->iov_len - base);
18
19                 base = 0;
20                 if (atomic)
21                         left = __copy_to_user_inatomic(buf, vaddr, copy);
22                 else
23                         left = __copy_to_user(buf, vaddr, copy);
24                 copied += copy;
25                 bytes -= copy;
26                 vaddr += copy;
27                 iov++;
28
29                 if (unlikely(left))
30                         break;
31         }
32         return copied - left;
33 }
34
35 /*
36  * Copy as much as we can into the page and return the number of bytes which
37  * were sucessfully copied.  If a fault is encountered then return the number of
38  * bytes which were copied.
39  */
40 static size_t ii_iovec_copy_to_user_atomic(struct page *page,
41                 struct iov_iter *i, unsigned long offset, size_t bytes)
42 {
43         struct iovec *iov = (struct iovec *)i->data;
44         char *kaddr;
45         size_t copied;
46
47         BUG_ON(!in_atomic());
48         kaddr = kmap_atomic(page);
49         if (likely(i->nr_segs == 1)) {
50                 int left;
51                 char __user *buf = iov->iov_base + i->iov_offset;
52                 left = __copy_to_user_inatomic(buf, kaddr + offset, bytes);
53                 copied = bytes - left;
54         } else {
55                 copied = __iovec_copy_to_user(kaddr + offset, iov,
56                                               i->iov_offset, bytes, 1);
57         }
58         kunmap_atomic(kaddr);
59
60         return copied;
61 }
62
63 /*
64  * This has the same sideeffects and return value as
65  * ii_iovec_copy_to_user_atomic().
66  * The difference is that it attempts to resolve faults.
67  * Page must not be locked.
68  */
69 static size_t ii_iovec_copy_to_user(struct page *page,
70                 struct iov_iter *i, unsigned long offset, size_t bytes,
71                 int check_access)
72 {
73         struct iovec *iov = (struct iovec *)i->data;
74         char *kaddr;
75         size_t copied;
76
77         if (check_access) {
78                 might_sleep();
79                 if (generic_segment_checks(iov, &i->nr_segs, &bytes,
80                                            VERIFY_WRITE))
81                         return 0;
82         }
83
84         if (likely(i->nr_segs == 1)) {
85                 int left;
86                 char __user *buf = iov->iov_base + i->iov_offset;
87                 /*
88                  * Faults on the destination of a read are common, so do it
89                  * before taking the kmap.
90                  */
91                 if (!fault_in_pages_writeable(buf, bytes)) {
92                         kaddr = kmap_atomic(page);
93                         left = __copy_to_user_inatomic(buf, kaddr + offset,
94                                                      bytes);
95                         kunmap_atomic(kaddr);
96                         if (left == 0)
97                                 goto success;
98                 }
99                 kaddr = kmap(page);
100                 left = copy_to_user(buf, kaddr + offset, bytes);
101                 kunmap(page);
102 success:
103                 copied = bytes - left;
104         } else {
105                 kaddr = kmap(page);
106                 copied = __iovec_copy_to_user(kaddr + offset, iov,
107                                               i->iov_offset, bytes, 0);
108                 kunmap(page);
109         }
110         return copied;
111 }
112
113 #ifdef CONFIG_BLOCK
114 /*
115  * As an easily verifiable first pass, we implement all the methods that
116  * copy data to and from bvec pages with one function.  We implement it
117  * all with kmap_atomic().
118  */
119 static size_t bvec_copy_tofrom_page(struct iov_iter *iter, struct page *page,
120                                     unsigned long page_offset, size_t bytes,
121                                     int topage)
122 {
123         struct bio_vec *bvec = (struct bio_vec *)iter->data;
124         size_t bvec_offset = iter->iov_offset;
125         size_t remaining = bytes;
126         void *bvec_map;
127         void *page_map;
128         size_t copy;
129
130         page_map = kmap_atomic(page);
131
132         BUG_ON(bytes > iter->count);
133         while (remaining) {
134                 BUG_ON(bvec->bv_len == 0);
135                 BUG_ON(bvec_offset >= bvec->bv_len);
136                 copy = min(remaining, bvec->bv_len - bvec_offset);
137                 bvec_map = kmap_atomic(bvec->bv_page);
138                 if (topage)
139                         memcpy(page_map + page_offset,
140                                bvec_map + bvec->bv_offset + bvec_offset,
141                                copy);
142                 else
143                         memcpy(bvec_map + bvec->bv_offset + bvec_offset,
144                                page_map + page_offset,
145                                copy);
146                 kunmap_atomic(bvec_map);
147                 remaining -= copy;
148                 bvec_offset += copy;
149                 page_offset += copy;
150                 if (bvec_offset == bvec->bv_len) {
151                         bvec_offset = 0;
152                         bvec++;
153                 }
154         }
155
156         kunmap_atomic(page_map);
157
158         return bytes;
159 }
160
161 static size_t ii_bvec_copy_to_user_atomic(struct page *page, struct iov_iter *i,
162                                           unsigned long offset, size_t bytes)
163 {
164         return bvec_copy_tofrom_page(i, page, offset, bytes, 0);
165 }
166 static size_t ii_bvec_copy_to_user(struct page *page, struct iov_iter *i,
167                                    unsigned long offset, size_t bytes,
168                                    int check_access)
169 {
170         return bvec_copy_tofrom_page(i, page, offset, bytes, 0);
171 }
172 static size_t ii_bvec_copy_from_user_atomic(struct page *page,
173                                             struct iov_iter *i,
174                                             unsigned long offset, size_t bytes)
175 {
176         return bvec_copy_tofrom_page(i, page, offset, bytes, 1);
177 }
178 static size_t ii_bvec_copy_from_user(struct page *page, struct iov_iter *i,
179                                      unsigned long offset, size_t bytes)
180 {
181         return bvec_copy_tofrom_page(i, page, offset, bytes, 1);
182 }
183
184 /*
185  * bio_vecs have a stricter structure than iovecs that might have
186  * come from userspace.  There are no zero length bio_vec elements.
187  */
188 static void ii_bvec_advance(struct iov_iter *i, size_t bytes)
189 {
190         struct bio_vec *bvec = (struct bio_vec *)i->data;
191         size_t offset = i->iov_offset;
192         size_t delta;
193
194         BUG_ON(i->count < bytes);
195         while (bytes) {
196                 BUG_ON(bvec->bv_len == 0);
197                 BUG_ON(bvec->bv_len <= offset);
198                 delta = min(bytes, bvec->bv_len - offset);
199                 offset += delta;
200                 i->count -= delta;
201                 bytes -= delta;
202                 if (offset == bvec->bv_len) {
203                         bvec++;
204                         offset = 0;
205                 }
206         }
207
208         i->data = (unsigned long)bvec;
209         i->iov_offset = offset;
210 }
211
212 /*
213  * pages pointed to by bio_vecs are always pinned.
214  */
215 static int ii_bvec_fault_in_readable(struct iov_iter *i, size_t bytes)
216 {
217         return 0;
218 }
219
220 static size_t ii_bvec_single_seg_count(const struct iov_iter *i)
221 {
222         const struct bio_vec *bvec = (struct bio_vec *)i->data;
223         if (i->nr_segs == 1)
224                 return i->count;
225         else
226                 return min(i->count, bvec->bv_len - i->iov_offset);
227 }
228
229 struct iov_iter_ops ii_bvec_ops = {
230         .ii_copy_to_user_atomic = ii_bvec_copy_to_user_atomic,
231         .ii_copy_to_user = ii_bvec_copy_to_user,
232         .ii_copy_from_user_atomic = ii_bvec_copy_from_user_atomic,
233         .ii_copy_from_user = ii_bvec_copy_from_user,
234         .ii_advance = ii_bvec_advance,
235         .ii_fault_in_readable = ii_bvec_fault_in_readable,
236         .ii_single_seg_count = ii_bvec_single_seg_count,
237 };
238 EXPORT_SYMBOL(ii_bvec_ops);
239 #endif  /* CONFIG_BLOCK */
240
241 static size_t __iovec_copy_from_user(char *vaddr, const struct iovec *iov,
242                                      size_t base, size_t bytes, int atomic)
243 {
244         size_t copied = 0, left = 0;
245
246         while (bytes) {
247                 char __user *buf = iov->iov_base + base;
248                 int copy = min(bytes, iov->iov_len - base);
249
250                 base = 0;
251                 if (atomic)
252                         left = __copy_from_user_inatomic(vaddr, buf, copy);
253                 else
254                         left = __copy_from_user(vaddr, buf, copy);
255                 copied += copy;
256                 bytes -= copy;
257                 vaddr += copy;
258                 iov++;
259
260                 if (unlikely(left))
261                         break;
262         }
263         return copied - left;
264 }
265
266 /*
267  * Copy as much as we can into the page and return the number of bytes which
268  * were successfully copied.  If a fault is encountered then return the number
269  * of bytes which were copied.
270  */
271 static size_t ii_iovec_copy_from_user_atomic(struct page *page,
272                 struct iov_iter *i, unsigned long offset, size_t bytes)
273 {
274         struct iovec *iov = (struct iovec *)i->data;
275         char *kaddr;
276         size_t copied;
277
278         BUG_ON(!in_atomic());
279         kaddr = kmap_atomic(page);
280         if (likely(i->nr_segs == 1)) {
281                 int left;
282                 char __user *buf = iov->iov_base + i->iov_offset;
283                 left = __copy_from_user_inatomic(kaddr + offset, buf, bytes);
284                 copied = bytes - left;
285         } else {
286                 copied = __iovec_copy_from_user(kaddr + offset, iov,
287                                                 i->iov_offset, bytes, 1);
288         }
289         kunmap_atomic(kaddr);
290
291         return copied;
292 }
293 EXPORT_SYMBOL(iov_iter_copy_from_user_atomic);
294
295 /*
296  * This has the same sideeffects and return value as
297  * ii_iovec_copy_from_user_atomic().
298  * The difference is that it attempts to resolve faults.
299  * Page must not be locked.
300  */
301 static size_t ii_iovec_copy_from_user(struct page *page,
302                 struct iov_iter *i, unsigned long offset, size_t bytes)
303 {
304         struct iovec *iov = (struct iovec *)i->data;
305         char *kaddr;
306         size_t copied;
307
308         kaddr = kmap(page);
309         if (likely(i->nr_segs == 1)) {
310                 int left;
311                 char __user *buf = iov->iov_base + i->iov_offset;
312                 left = __copy_from_user(kaddr + offset, buf, bytes);
313                 copied = bytes - left;
314         } else {
315                 copied = __iovec_copy_from_user(kaddr + offset, iov,
316                                                 i->iov_offset, bytes, 0);
317         }
318         kunmap(page);
319         return copied;
320 }
321
322 static void ii_iovec_advance(struct iov_iter *i, size_t bytes)
323 {
324         BUG_ON(i->count < bytes);
325
326         if (likely(i->nr_segs == 1)) {
327                 i->iov_offset += bytes;
328                 i->count -= bytes;
329         } else {
330                 struct iovec *iov = (struct iovec *)i->data;
331                 size_t base = i->iov_offset;
332                 unsigned long nr_segs = i->nr_segs;
333
334                 /*
335                  * The !iov->iov_len check ensures we skip over unlikely
336                  * zero-length segments (without overruning the iovec).
337                  */
338                 while (bytes || unlikely(i->count && !iov->iov_len)) {
339                         int copy;
340
341                         copy = min(bytes, iov->iov_len - base);
342                         BUG_ON(!i->count || i->count < copy);
343                         i->count -= copy;
344                         bytes -= copy;
345                         base += copy;
346                         if (iov->iov_len == base) {
347                                 iov++;
348                                 nr_segs--;
349                                 base = 0;
350                         }
351                 }
352                 i->data = (unsigned long)iov;
353                 i->iov_offset = base;
354                 i->nr_segs = nr_segs;
355         }
356 }
357
358 /*
359  * Fault in the first iovec of the given iov_iter, to a maximum length
360  * of bytes. Returns 0 on success, or non-zero if the memory could not be
361  * accessed (ie. because it is an invalid address).
362  *
363  * writev-intensive code may want this to prefault several iovecs -- that
364  * would be possible (callers must not rely on the fact that _only_ the
365  * first iovec will be faulted with the current implementation).
366  */
367 static int ii_iovec_fault_in_readable(struct iov_iter *i, size_t bytes)
368 {
369         struct iovec *iov = (struct iovec *)i->data;
370         char __user *buf = iov->iov_base + i->iov_offset;
371         bytes = min(bytes, iov->iov_len - i->iov_offset);
372         return fault_in_pages_readable(buf, bytes);
373 }
374
375 /*
376  * Return the count of just the current iov_iter segment.
377  */
378 static size_t ii_iovec_single_seg_count(const struct iov_iter *i)
379 {
380         const struct iovec *iov = (struct iovec *)i->data;
381         if (i->nr_segs == 1)
382                 return i->count;
383         else
384                 return min(i->count, iov->iov_len - i->iov_offset);
385 }
386
387 struct iov_iter_ops ii_iovec_ops = {
388         .ii_copy_to_user_atomic = ii_iovec_copy_to_user_atomic,
389         .ii_copy_to_user = ii_iovec_copy_to_user,
390         .ii_copy_from_user_atomic = ii_iovec_copy_from_user_atomic,
391         .ii_copy_from_user = ii_iovec_copy_from_user,
392         .ii_advance = ii_iovec_advance,
393         .ii_fault_in_readable = ii_iovec_fault_in_readable,
394         .ii_single_seg_count = ii_iovec_single_seg_count,
395 };
396 EXPORT_SYMBOL(ii_iovec_ops);