aboutsummaryrefslogtreecommitdiffstats
path: root/mm/iov_iter.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2014-11-27 14:18:54 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2014-11-27 18:44:12 -0500
commit8442fa46cf244cd65401f1a5bb830ed420fc1e54 (patch)
tree15e36811668838fa6573c630587a98daceb4e80d /mm/iov_iter.c
parent1b17f1f2e56a091deb99a068a6f1e82b5bb76b09 (diff)
iov_iter.c: convert iov_iter_zero() to iterate_and_advance
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'mm/iov_iter.c')
-rw-r--r--mm/iov_iter.c98
1 files changed, 12 insertions, 86 deletions
diff --git a/mm/iov_iter.c b/mm/iov_iter.c
index 3214b9b493ae..39ad7137f739 100644
--- a/mm/iov_iter.c
+++ b/mm/iov_iter.c
@@ -349,50 +349,6 @@ done:
349 return wanted - bytes; 349 return wanted - bytes;
350} 350}
351 351
352static size_t zero_iovec(size_t bytes, struct iov_iter *i)
353{
354 size_t skip, copy, left, wanted;
355 const struct iovec *iov;
356 char __user *buf;
357
358 if (unlikely(bytes > i->count))
359 bytes = i->count;
360
361 if (unlikely(!bytes))
362 return 0;
363
364 wanted = bytes;
365 iov = i->iov;
366 skip = i->iov_offset;
367 buf = iov->iov_base + skip;
368 copy = min(bytes, iov->iov_len - skip);
369
370 left = __clear_user(buf, copy);
371 copy -= left;
372 skip += copy;
373 bytes -= copy;
374
375 while (unlikely(!left && bytes)) {
376 iov++;
377 buf = iov->iov_base;
378 copy = min(bytes, iov->iov_len);
379 left = __clear_user(buf, copy);
380 copy -= left;
381 skip = copy;
382 bytes -= copy;
383 }
384
385 if (skip == iov->iov_len) {
386 iov++;
387 skip = 0;
388 }
389 i->count -= wanted - bytes;
390 i->nr_segs -= iov - i->iov;
391 i->iov = iov;
392 i->iov_offset = skip;
393 return wanted - bytes;
394}
395
396/* 352/*
397 * Fault in the first iovec of the given iov_iter, to a maximum length 353 * Fault in the first iovec of the given iov_iter, to a maximum length
398 * of bytes. Returns 0 on success, or non-zero if the memory could not be 354 * of bytes. Returns 0 on success, or non-zero if the memory could not be
@@ -548,43 +504,6 @@ static size_t copy_page_from_iter_bvec(struct page *page, size_t offset,
548 return wanted; 504 return wanted;
549} 505}
550 506
551static size_t zero_bvec(size_t bytes, struct iov_iter *i)
552{
553 size_t skip, copy, wanted;
554 const struct bio_vec *bvec;
555
556 if (unlikely(bytes > i->count))
557 bytes = i->count;
558
559 if (unlikely(!bytes))
560 return 0;
561
562 wanted = bytes;
563 bvec = i->bvec;
564 skip = i->iov_offset;
565 copy = min_t(size_t, bytes, bvec->bv_len - skip);
566
567 memzero_page(bvec->bv_page, skip + bvec->bv_offset, copy);
568 skip += copy;
569 bytes -= copy;
570 while (bytes) {
571 bvec++;
572 copy = min(bytes, (size_t)bvec->bv_len);
573 memzero_page(bvec->bv_page, bvec->bv_offset, copy);
574 skip = copy;
575 bytes -= copy;
576 }
577 if (skip == bvec->bv_len) {
578 bvec++;
579 skip = 0;
580 }
581 i->count -= wanted - bytes;
582 i->nr_segs -= bvec - i->bvec;
583 i->bvec = bvec;
584 i->iov_offset = skip;
585 return wanted - bytes;
586}
587
588size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes, 507size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes,
589 struct iov_iter *i) 508 struct iov_iter *i)
590{ 509{
@@ -625,11 +544,18 @@ EXPORT_SYMBOL(copy_from_iter);
625 544
626size_t iov_iter_zero(size_t bytes, struct iov_iter *i) 545size_t iov_iter_zero(size_t bytes, struct iov_iter *i)
627{ 546{
628 if (i->type & ITER_BVEC) { 547 if (unlikely(bytes > i->count))
629 return zero_bvec(bytes, i); 548 bytes = i->count;
630 } else { 549
631 return zero_iovec(bytes, i); 550 if (unlikely(!bytes))
632 } 551 return 0;
552
553 iterate_and_advance(i, bytes, v,
554 __clear_user(v.iov_base, v.iov_len),
555 memzero_page(v.bv_page, v.bv_offset, v.bv_len)
556 )
557
558 return bytes;
633} 559}
634EXPORT_SYMBOL(iov_iter_zero); 560EXPORT_SYMBOL(iov_iter_zero);
635 561