Commit e5393fae3b49e80179f04afdc0916fcb6846ef17
1 parent
e0f2dc4061
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
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
mm/iov_iter.c
... | ... | @@ -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 |