Commit e5393fae3b49e80179f04afdc0916fcb6846ef17

Authored by Al Viro
1 parent e0f2dc4061

iov_iter.c: convert iov_iter_get_pages() to iterate_all_kinds

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Showing 1 changed file with 28 additions and 50 deletions Side-by-side Diff

... ... @@ -428,34 +428,6 @@
428 428 }
429 429 EXPORT_SYMBOL(iov_iter_init);
430 430  
431   -static ssize_t get_pages_iovec(struct iov_iter *i,
432   - struct page **pages, size_t maxsize, unsigned maxpages,
433   - size_t *start)
434   -{
435   - size_t offset = i->iov_offset;
436   - const struct iovec *iov = i->iov;
437   - size_t len;
438   - unsigned long addr;
439   - int n;
440   - int res;
441   -
442   - len = iov->iov_len - offset;
443   - if (len > i->count)
444   - len = i->count;
445   - if (len > maxsize)
446   - len = maxsize;
447   - addr = (unsigned long)iov->iov_base + offset;
448   - len += *start = addr & (PAGE_SIZE - 1);
449   - if (len > maxpages * PAGE_SIZE)
450   - len = maxpages * PAGE_SIZE;
451   - addr &= ~(PAGE_SIZE - 1);
452   - n = (len + PAGE_SIZE - 1) / PAGE_SIZE;
453   - res = get_user_pages_fast(addr, n, (i->type & WRITE) != WRITE, pages);
454   - if (unlikely(res < 0))
455   - return res;
456   - return (res == n ? len : res * PAGE_SIZE) - *start;
457   -}
458   -
459 431 static ssize_t get_pages_alloc_iovec(struct iov_iter *i,
460 432 struct page ***pages, size_t maxsize,
461 433 size_t *start)
... ... @@ -650,24 +622,6 @@
650 622 return wanted - bytes;
651 623 }
652 624  
653   -static ssize_t get_pages_bvec(struct iov_iter *i,
654   - struct page **pages, size_t maxsize, unsigned maxpages,
655   - size_t *start)
656   -{
657   - const struct bio_vec *bvec = i->bvec;
658   - size_t len = bvec->bv_len - i->iov_offset;
659   - if (len > i->count)
660   - len = i->count;
661   - if (len > maxsize)
662   - len = maxsize;
663   - /* can't be more than PAGE_SIZE */
664   - *start = bvec->bv_offset + i->iov_offset;
665   -
666   - get_page(*pages = bvec->bv_page);
667   -
668   - return len;
669   -}
670   -
671 625 static ssize_t get_pages_alloc_bvec(struct iov_iter *i,
672 626 struct page ***pages, size_t maxsize,
673 627 size_t *start)
... ... @@ -792,10 +746,34 @@
792 746 struct page **pages, size_t maxsize, unsigned maxpages,
793 747 size_t *start)
794 748 {
795   - if (i->type & ITER_BVEC)
796   - return get_pages_bvec(i, pages, maxsize, maxpages, start);
797   - else
798   - return get_pages_iovec(i, pages, maxsize, maxpages, start);
  749 + if (maxsize > i->count)
  750 + maxsize = i->count;
  751 +
  752 + if (!maxsize)
  753 + return 0;
  754 +
  755 + iterate_all_kinds(i, maxsize, v, ({
  756 + unsigned long addr = (unsigned long)v.iov_base;
  757 + size_t len = v.iov_len + (*start = addr & (PAGE_SIZE - 1));
  758 + int n;
  759 + int res;
  760 +
  761 + if (len > maxpages * PAGE_SIZE)
  762 + len = maxpages * PAGE_SIZE;
  763 + addr &= ~(PAGE_SIZE - 1);
  764 + n = DIV_ROUND_UP(len, PAGE_SIZE);
  765 + res = get_user_pages_fast(addr, n, (i->type & WRITE) != WRITE, pages);
  766 + if (unlikely(res < 0))
  767 + return res;
  768 + return (res == n ? len : res * PAGE_SIZE) - *start;
  769 + 0;}),({
  770 + /* can't be more than PAGE_SIZE */
  771 + *start = v.bv_offset;
  772 + get_page(*pages = v.bv_page);
  773 + return v.bv_len;
  774 + })
  775 + )
  776 + return 0;
799 777 }
800 778 EXPORT_SYMBOL(iov_iter_get_pages);
801 779