]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - mm/iov_iter.c
iov_iter.c: convert copy_from_iter() to iterate_and_advance
[mirror_ubuntu-artful-kernel.git] / mm / iov_iter.c
CommitLineData
4f18cd31
AV
1#include <linux/export.h>
2#include <linux/uio.h>
3#include <linux/pagemap.h>
91f79c43
AV
4#include <linux/slab.h>
5#include <linux/vmalloc.h>
4f18cd31 6
04a31165
AV
7#define iterate_iovec(i, n, __v, __p, skip, STEP) { \
8 size_t left; \
9 size_t wanted = n; \
10 __p = i->iov; \
11 __v.iov_len = min(n, __p->iov_len - skip); \
12 if (likely(__v.iov_len)) { \
13 __v.iov_base = __p->iov_base + skip; \
14 left = (STEP); \
15 __v.iov_len -= left; \
16 skip += __v.iov_len; \
17 n -= __v.iov_len; \
18 } else { \
19 left = 0; \
20 } \
21 while (unlikely(!left && n)) { \
22 __p++; \
23 __v.iov_len = min(n, __p->iov_len); \
24 if (unlikely(!__v.iov_len)) \
25 continue; \
26 __v.iov_base = __p->iov_base; \
27 left = (STEP); \
28 __v.iov_len -= left; \
29 skip = __v.iov_len; \
30 n -= __v.iov_len; \
31 } \
32 n = wanted - n; \
33}
34
35#define iterate_bvec(i, n, __v, __p, skip, STEP) { \
36 size_t wanted = n; \
37 __p = i->bvec; \
38 __v.bv_len = min_t(size_t, n, __p->bv_len - skip); \
39 if (likely(__v.bv_len)) { \
40 __v.bv_page = __p->bv_page; \
41 __v.bv_offset = __p->bv_offset + skip; \
42 (void)(STEP); \
43 skip += __v.bv_len; \
44 n -= __v.bv_len; \
45 } \
46 while (unlikely(n)) { \
47 __p++; \
48 __v.bv_len = min_t(size_t, n, __p->bv_len); \
49 if (unlikely(!__v.bv_len)) \
50 continue; \
51 __v.bv_page = __p->bv_page; \
52 __v.bv_offset = __p->bv_offset; \
53 (void)(STEP); \
54 skip = __v.bv_len; \
55 n -= __v.bv_len; \
56 } \
57 n = wanted; \
58}
59
60#define iterate_all_kinds(i, n, v, I, B) { \
61 size_t skip = i->iov_offset; \
62 if (unlikely(i->type & ITER_BVEC)) { \
63 const struct bio_vec *bvec; \
64 struct bio_vec v; \
65 iterate_bvec(i, n, v, bvec, skip, (B)) \
66 } else { \
67 const struct iovec *iov; \
68 struct iovec v; \
69 iterate_iovec(i, n, v, iov, skip, (I)) \
70 } \
71}
72
7ce2a91e
AV
73#define iterate_and_advance(i, n, v, I, B) { \
74 size_t skip = i->iov_offset; \
75 if (unlikely(i->type & ITER_BVEC)) { \
76 const struct bio_vec *bvec; \
77 struct bio_vec v; \
78 iterate_bvec(i, n, v, bvec, skip, (B)) \
79 if (skip == bvec->bv_len) { \
80 bvec++; \
81 skip = 0; \
82 } \
83 i->nr_segs -= bvec - i->bvec; \
84 i->bvec = bvec; \
85 } else { \
86 const struct iovec *iov; \
87 struct iovec v; \
88 iterate_iovec(i, n, v, iov, skip, (I)) \
89 if (skip == iov->iov_len) { \
90 iov++; \
91 skip = 0; \
92 } \
93 i->nr_segs -= iov - i->iov; \
94 i->iov = iov; \
95 } \
96 i->count -= n; \
97 i->iov_offset = skip; \
98}
99
c35e0248
MW
100static size_t copy_to_iter_iovec(void *from, size_t bytes, struct iov_iter *i)
101{
102 size_t skip, copy, left, wanted;
103 const struct iovec *iov;
104 char __user *buf;
105
106 if (unlikely(bytes > i->count))
107 bytes = i->count;
108
109 if (unlikely(!bytes))
110 return 0;
111
112 wanted = bytes;
113 iov = i->iov;
114 skip = i->iov_offset;
115 buf = iov->iov_base + skip;
116 copy = min(bytes, iov->iov_len - skip);
117
118 left = __copy_to_user(buf, from, copy);
119 copy -= left;
120 skip += copy;
121 from += copy;
122 bytes -= copy;
123 while (unlikely(!left && bytes)) {
124 iov++;
125 buf = iov->iov_base;
126 copy = min(bytes, iov->iov_len);
127 left = __copy_to_user(buf, from, copy);
128 copy -= left;
129 skip = copy;
130 from += copy;
131 bytes -= copy;
132 }
133
134 if (skip == iov->iov_len) {
135 iov++;
136 skip = 0;
137 }
138 i->count -= wanted - bytes;
139 i->nr_segs -= iov - i->iov;
140 i->iov = iov;
141 i->iov_offset = skip;
142 return wanted - bytes;
143}
144
62a8067a 145static size_t copy_page_to_iter_iovec(struct page *page, size_t offset, size_t bytes,
4f18cd31
AV
146 struct iov_iter *i)
147{
148 size_t skip, copy, left, wanted;
149 const struct iovec *iov;
150 char __user *buf;
151 void *kaddr, *from;
152
153 if (unlikely(bytes > i->count))
154 bytes = i->count;
155
156 if (unlikely(!bytes))
157 return 0;
158
159 wanted = bytes;
160 iov = i->iov;
161 skip = i->iov_offset;
162 buf = iov->iov_base + skip;
163 copy = min(bytes, iov->iov_len - skip);
164
165 if (!fault_in_pages_writeable(buf, copy)) {
166 kaddr = kmap_atomic(page);
167 from = kaddr + offset;
168
169 /* first chunk, usually the only one */
170 left = __copy_to_user_inatomic(buf, from, copy);
171 copy -= left;
172 skip += copy;
173 from += copy;
174 bytes -= copy;
175
176 while (unlikely(!left && bytes)) {
177 iov++;
178 buf = iov->iov_base;
179 copy = min(bytes, iov->iov_len);
180 left = __copy_to_user_inatomic(buf, from, copy);
181 copy -= left;
182 skip = copy;
183 from += copy;
184 bytes -= copy;
185 }
186 if (likely(!bytes)) {
187 kunmap_atomic(kaddr);
188 goto done;
189 }
190 offset = from - kaddr;
191 buf += copy;
192 kunmap_atomic(kaddr);
193 copy = min(bytes, iov->iov_len - skip);
194 }
195 /* Too bad - revert to non-atomic kmap */
196 kaddr = kmap(page);
197 from = kaddr + offset;
198 left = __copy_to_user(buf, from, copy);
199 copy -= left;
200 skip += copy;
201 from += copy;
202 bytes -= copy;
203 while (unlikely(!left && bytes)) {
204 iov++;
205 buf = iov->iov_base;
206 copy = min(bytes, iov->iov_len);
207 left = __copy_to_user(buf, from, copy);
208 copy -= left;
209 skip = copy;
210 from += copy;
211 bytes -= copy;
212 }
213 kunmap(page);
214done:
81055e58
AV
215 if (skip == iov->iov_len) {
216 iov++;
217 skip = 0;
218 }
4f18cd31
AV
219 i->count -= wanted - bytes;
220 i->nr_segs -= iov - i->iov;
221 i->iov = iov;
222 i->iov_offset = skip;
223 return wanted - bytes;
224}
4f18cd31 225
62a8067a 226static size_t copy_page_from_iter_iovec(struct page *page, size_t offset, size_t bytes,
f0d1bec9
AV
227 struct iov_iter *i)
228{
229 size_t skip, copy, left, wanted;
230 const struct iovec *iov;
231 char __user *buf;
232 void *kaddr, *to;
233
234 if (unlikely(bytes > i->count))
235 bytes = i->count;
236
237 if (unlikely(!bytes))
238 return 0;
239
240 wanted = bytes;
241 iov = i->iov;
242 skip = i->iov_offset;
243 buf = iov->iov_base + skip;
244 copy = min(bytes, iov->iov_len - skip);
245
246 if (!fault_in_pages_readable(buf, copy)) {
247 kaddr = kmap_atomic(page);
248 to = kaddr + offset;
249
250 /* first chunk, usually the only one */
251 left = __copy_from_user_inatomic(to, buf, copy);
252 copy -= left;
253 skip += copy;
254 to += copy;
255 bytes -= copy;
256
257 while (unlikely(!left && bytes)) {
258 iov++;
259 buf = iov->iov_base;
260 copy = min(bytes, iov->iov_len);
261 left = __copy_from_user_inatomic(to, buf, copy);
262 copy -= left;
263 skip = copy;
264 to += copy;
265 bytes -= copy;
266 }
267 if (likely(!bytes)) {
268 kunmap_atomic(kaddr);
269 goto done;
270 }
271 offset = to - kaddr;
272 buf += copy;
273 kunmap_atomic(kaddr);
274 copy = min(bytes, iov->iov_len - skip);
275 }
276 /* Too bad - revert to non-atomic kmap */
277 kaddr = kmap(page);
278 to = kaddr + offset;
279 left = __copy_from_user(to, buf, copy);
280 copy -= left;
281 skip += copy;
282 to += copy;
283 bytes -= copy;
284 while (unlikely(!left && bytes)) {
285 iov++;
286 buf = iov->iov_base;
287 copy = min(bytes, iov->iov_len);
288 left = __copy_from_user(to, buf, copy);
289 copy -= left;
290 skip = copy;
291 to += copy;
292 bytes -= copy;
293 }
294 kunmap(page);
295done:
81055e58
AV
296 if (skip == iov->iov_len) {
297 iov++;
298 skip = 0;
299 }
f0d1bec9
AV
300 i->count -= wanted - bytes;
301 i->nr_segs -= iov - i->iov;
302 i->iov = iov;
303 i->iov_offset = skip;
304 return wanted - bytes;
305}
f0d1bec9 306
4f18cd31
AV
307/*
308 * Fault in the first iovec of the given iov_iter, to a maximum length
309 * of bytes. Returns 0 on success, or non-zero if the memory could not be
310 * accessed (ie. because it is an invalid address).
311 *
312 * writev-intensive code may want this to prefault several iovecs -- that
313 * would be possible (callers must not rely on the fact that _only_ the
314 * first iovec will be faulted with the current implementation).
315 */
316int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes)
317{
62a8067a
AV
318 if (!(i->type & ITER_BVEC)) {
319 char __user *buf = i->iov->iov_base + i->iov_offset;
320 bytes = min(bytes, i->iov->iov_len - i->iov_offset);
321 return fault_in_pages_readable(buf, bytes);
322 }
323 return 0;
4f18cd31
AV
324}
325EXPORT_SYMBOL(iov_iter_fault_in_readable);
326
71d8e532
AV
327void iov_iter_init(struct iov_iter *i, int direction,
328 const struct iovec *iov, unsigned long nr_segs,
329 size_t count)
330{
331 /* It will get better. Eventually... */
332 if (segment_eq(get_fs(), KERNEL_DS))
62a8067a 333 direction |= ITER_KVEC;
71d8e532
AV
334 i->type = direction;
335 i->iov = iov;
336 i->nr_segs = nr_segs;
337 i->iov_offset = 0;
338 i->count = count;
339}
340EXPORT_SYMBOL(iov_iter_init);
7b2c99d1 341
62a8067a
AV
342static void memcpy_from_page(char *to, struct page *page, size_t offset, size_t len)
343{
344 char *from = kmap_atomic(page);
345 memcpy(to, from + offset, len);
346 kunmap_atomic(from);
347}
348
349static void memcpy_to_page(struct page *page, size_t offset, char *from, size_t len)
350{
351 char *to = kmap_atomic(page);
352 memcpy(to + offset, from, len);
353 kunmap_atomic(to);
354}
355
c35e0248
MW
356static void memzero_page(struct page *page, size_t offset, size_t len)
357{
358 char *addr = kmap_atomic(page);
359 memset(addr + offset, 0, len);
360 kunmap_atomic(addr);
361}
362
363static size_t copy_to_iter_bvec(void *from, size_t bytes, struct iov_iter *i)
62a8067a
AV
364{
365 size_t skip, copy, wanted;
366 const struct bio_vec *bvec;
62a8067a
AV
367
368 if (unlikely(bytes > i->count))
369 bytes = i->count;
370
371 if (unlikely(!bytes))
372 return 0;
373
374 wanted = bytes;
375 bvec = i->bvec;
376 skip = i->iov_offset;
377 copy = min_t(size_t, bytes, bvec->bv_len - skip);
378
62a8067a
AV
379 memcpy_to_page(bvec->bv_page, skip + bvec->bv_offset, from, copy);
380 skip += copy;
381 from += copy;
382 bytes -= copy;
383 while (bytes) {
384 bvec++;
385 copy = min(bytes, (size_t)bvec->bv_len);
386 memcpy_to_page(bvec->bv_page, bvec->bv_offset, from, copy);
387 skip = copy;
388 from += copy;
389 bytes -= copy;
390 }
62a8067a
AV
391 if (skip == bvec->bv_len) {
392 bvec++;
393 skip = 0;
394 }
395 i->count -= wanted - bytes;
396 i->nr_segs -= bvec - i->bvec;
397 i->bvec = bvec;
398 i->iov_offset = skip;
399 return wanted - bytes;
400}
401
d271524a 402size_t copy_to_iter(void *addr, size_t bytes, struct iov_iter *i)
c35e0248 403{
d271524a
AV
404 if (i->type & ITER_BVEC)
405 return copy_to_iter_bvec(addr, bytes, i);
406 else
407 return copy_to_iter_iovec(addr, bytes, i);
c35e0248 408}
d271524a 409EXPORT_SYMBOL(copy_to_iter);
c35e0248 410
d271524a 411size_t copy_from_iter(void *addr, size_t bytes, struct iov_iter *i)
c35e0248 412{
0dbca9a4
AV
413 char *to = addr;
414 if (unlikely(bytes > i->count))
415 bytes = i->count;
416
417 if (unlikely(!bytes))
418 return 0;
419
420 iterate_and_advance(i, bytes, v,
421 __copy_from_user((to += v.iov_len) - v.iov_len, v.iov_base,
422 v.iov_len),
423 memcpy_from_page((to += v.bv_len) - v.bv_len, v.bv_page,
424 v.bv_offset, v.bv_len)
425 )
426
427 return bytes;
c35e0248 428}
d271524a 429EXPORT_SYMBOL(copy_from_iter);
c35e0248 430
62a8067a
AV
431size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes,
432 struct iov_iter *i)
433{
d271524a
AV
434 if (i->type & (ITER_BVEC|ITER_KVEC)) {
435 void *kaddr = kmap_atomic(page);
436 size_t wanted = copy_to_iter(kaddr + offset, bytes, i);
437 kunmap_atomic(kaddr);
438 return wanted;
439 } else
62a8067a
AV
440 return copy_page_to_iter_iovec(page, offset, bytes, i);
441}
442EXPORT_SYMBOL(copy_page_to_iter);
443
444size_t copy_page_from_iter(struct page *page, size_t offset, size_t bytes,
445 struct iov_iter *i)
446{
d271524a
AV
447 if (i->type & ITER_BVEC) {
448 void *kaddr = kmap_atomic(page);
449 size_t wanted = copy_from_iter(kaddr + offset, bytes, i);
450 kunmap_atomic(kaddr);
451 return wanted;
452 } else
62a8067a
AV
453 return copy_page_from_iter_iovec(page, offset, bytes, i);
454}
455EXPORT_SYMBOL(copy_page_from_iter);
456
c35e0248
MW
457size_t iov_iter_zero(size_t bytes, struct iov_iter *i)
458{
8442fa46
AV
459 if (unlikely(bytes > i->count))
460 bytes = i->count;
461
462 if (unlikely(!bytes))
463 return 0;
464
465 iterate_and_advance(i, bytes, v,
466 __clear_user(v.iov_base, v.iov_len),
467 memzero_page(v.bv_page, v.bv_offset, v.bv_len)
468 )
469
470 return bytes;
c35e0248
MW
471}
472EXPORT_SYMBOL(iov_iter_zero);
473
62a8067a
AV
474size_t iov_iter_copy_from_user_atomic(struct page *page,
475 struct iov_iter *i, unsigned long offset, size_t bytes)
476{
04a31165
AV
477 char *kaddr = kmap_atomic(page), *p = kaddr + offset;
478 iterate_all_kinds(i, bytes, v,
479 __copy_from_user_inatomic((p += v.iov_len) - v.iov_len,
480 v.iov_base, v.iov_len),
481 memcpy_from_page((p += v.bv_len) - v.bv_len, v.bv_page,
482 v.bv_offset, v.bv_len)
483 )
484 kunmap_atomic(kaddr);
485 return bytes;
62a8067a
AV
486}
487EXPORT_SYMBOL(iov_iter_copy_from_user_atomic);
488
489void iov_iter_advance(struct iov_iter *i, size_t size)
490{
7ce2a91e 491 iterate_and_advance(i, size, v, 0, 0)
62a8067a
AV
492}
493EXPORT_SYMBOL(iov_iter_advance);
494
495/*
496 * Return the count of just the current iov_iter segment.
497 */
498size_t iov_iter_single_seg_count(const struct iov_iter *i)
499{
500 if (i->nr_segs == 1)
501 return i->count;
502 else if (i->type & ITER_BVEC)
62a8067a 503 return min(i->count, i->bvec->bv_len - i->iov_offset);
ad0eab92
PM
504 else
505 return min(i->count, i->iov->iov_len - i->iov_offset);
62a8067a
AV
506}
507EXPORT_SYMBOL(iov_iter_single_seg_count);
508
509unsigned long iov_iter_alignment(const struct iov_iter *i)
510{
04a31165
AV
511 unsigned long res = 0;
512 size_t size = i->count;
513
514 if (!size)
515 return 0;
516
517 iterate_all_kinds(i, size, v,
518 (res |= (unsigned long)v.iov_base | v.iov_len, 0),
519 res |= v.bv_offset | v.bv_len
520 )
521 return res;
62a8067a
AV
522}
523EXPORT_SYMBOL(iov_iter_alignment);
524
525ssize_t iov_iter_get_pages(struct iov_iter *i,
2c80929c 526 struct page **pages, size_t maxsize, unsigned maxpages,
62a8067a
AV
527 size_t *start)
528{
e5393fae
AV
529 if (maxsize > i->count)
530 maxsize = i->count;
531
532 if (!maxsize)
533 return 0;
534
535 iterate_all_kinds(i, maxsize, v, ({
536 unsigned long addr = (unsigned long)v.iov_base;
537 size_t len = v.iov_len + (*start = addr & (PAGE_SIZE - 1));
538 int n;
539 int res;
540
541 if (len > maxpages * PAGE_SIZE)
542 len = maxpages * PAGE_SIZE;
543 addr &= ~(PAGE_SIZE - 1);
544 n = DIV_ROUND_UP(len, PAGE_SIZE);
545 res = get_user_pages_fast(addr, n, (i->type & WRITE) != WRITE, pages);
546 if (unlikely(res < 0))
547 return res;
548 return (res == n ? len : res * PAGE_SIZE) - *start;
549 0;}),({
550 /* can't be more than PAGE_SIZE */
551 *start = v.bv_offset;
552 get_page(*pages = v.bv_page);
553 return v.bv_len;
554 })
555 )
556 return 0;
62a8067a
AV
557}
558EXPORT_SYMBOL(iov_iter_get_pages);
559
1b17f1f2
AV
560static struct page **get_pages_array(size_t n)
561{
562 struct page **p = kmalloc(n * sizeof(struct page *), GFP_KERNEL);
563 if (!p)
564 p = vmalloc(n * sizeof(struct page *));
565 return p;
566}
567
62a8067a
AV
568ssize_t iov_iter_get_pages_alloc(struct iov_iter *i,
569 struct page ***pages, size_t maxsize,
570 size_t *start)
571{
1b17f1f2
AV
572 struct page **p;
573
574 if (maxsize > i->count)
575 maxsize = i->count;
576
577 if (!maxsize)
578 return 0;
579
580 iterate_all_kinds(i, maxsize, v, ({
581 unsigned long addr = (unsigned long)v.iov_base;
582 size_t len = v.iov_len + (*start = addr & (PAGE_SIZE - 1));
583 int n;
584 int res;
585
586 addr &= ~(PAGE_SIZE - 1);
587 n = DIV_ROUND_UP(len, PAGE_SIZE);
588 p = get_pages_array(n);
589 if (!p)
590 return -ENOMEM;
591 res = get_user_pages_fast(addr, n, (i->type & WRITE) != WRITE, p);
592 if (unlikely(res < 0)) {
593 kvfree(p);
594 return res;
595 }
596 *pages = p;
597 return (res == n ? len : res * PAGE_SIZE) - *start;
598 0;}),({
599 /* can't be more than PAGE_SIZE */
600 *start = v.bv_offset;
601 *pages = p = get_pages_array(1);
602 if (!p)
603 return -ENOMEM;
604 get_page(*p = v.bv_page);
605 return v.bv_len;
606 })
607 )
608 return 0;
62a8067a
AV
609}
610EXPORT_SYMBOL(iov_iter_get_pages_alloc);
611
612int iov_iter_npages(const struct iov_iter *i, int maxpages)
613{
e0f2dc40
AV
614 size_t size = i->count;
615 int npages = 0;
616
617 if (!size)
618 return 0;
619
620 iterate_all_kinds(i, size, v, ({
621 unsigned long p = (unsigned long)v.iov_base;
622 npages += DIV_ROUND_UP(p + v.iov_len, PAGE_SIZE)
623 - p / PAGE_SIZE;
624 if (npages >= maxpages)
625 return maxpages;
626 0;}),({
627 npages++;
628 if (npages >= maxpages)
629 return maxpages;
630 })
631 )
632 return npages;
62a8067a 633}
f67da30c 634EXPORT_SYMBOL(iov_iter_npages);