diff options
Diffstat (limited to 'lib/iov_iter.c')
-rw-r--r-- | lib/iov_iter.c | 125 |
1 files changed, 84 insertions, 41 deletions
diff --git a/lib/iov_iter.c b/lib/iov_iter.c index 8be175df3075..7ebccb5c1637 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c | |||
@@ -83,6 +83,7 @@ | |||
83 | const struct kvec *kvec; \ | 83 | const struct kvec *kvec; \ |
84 | struct kvec v; \ | 84 | struct kvec v; \ |
85 | iterate_kvec(i, n, v, kvec, skip, (K)) \ | 85 | iterate_kvec(i, n, v, kvec, skip, (K)) \ |
86 | } else if (unlikely(i->type & ITER_DISCARD)) { \ | ||
86 | } else { \ | 87 | } else { \ |
87 | const struct iovec *iov; \ | 88 | const struct iovec *iov; \ |
88 | struct iovec v; \ | 89 | struct iovec v; \ |
@@ -114,6 +115,8 @@ | |||
114 | } \ | 115 | } \ |
115 | i->nr_segs -= kvec - i->kvec; \ | 116 | i->nr_segs -= kvec - i->kvec; \ |
116 | i->kvec = kvec; \ | 117 | i->kvec = kvec; \ |
118 | } else if (unlikely(i->type & ITER_DISCARD)) { \ | ||
119 | skip += n; \ | ||
117 | } else { \ | 120 | } else { \ |
118 | const struct iovec *iov; \ | 121 | const struct iovec *iov; \ |
119 | struct iovec v; \ | 122 | struct iovec v; \ |
@@ -428,17 +431,19 @@ int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes) | |||
428 | } | 431 | } |
429 | EXPORT_SYMBOL(iov_iter_fault_in_readable); | 432 | EXPORT_SYMBOL(iov_iter_fault_in_readable); |
430 | 433 | ||
431 | void iov_iter_init(struct iov_iter *i, int direction, | 434 | void iov_iter_init(struct iov_iter *i, unsigned int direction, |
432 | const struct iovec *iov, unsigned long nr_segs, | 435 | const struct iovec *iov, unsigned long nr_segs, |
433 | size_t count) | 436 | size_t count) |
434 | { | 437 | { |
438 | WARN_ON(direction & ~(READ | WRITE)); | ||
439 | direction &= READ | WRITE; | ||
440 | |||
435 | /* It will get better. Eventually... */ | 441 | /* It will get better. Eventually... */ |
436 | if (uaccess_kernel()) { | 442 | if (uaccess_kernel()) { |
437 | direction |= ITER_KVEC; | 443 | i->type = ITER_KVEC | direction; |
438 | i->type = direction; | ||
439 | i->kvec = (struct kvec *)iov; | 444 | i->kvec = (struct kvec *)iov; |
440 | } else { | 445 | } else { |
441 | i->type = direction; | 446 | i->type = ITER_IOVEC | direction; |
442 | i->iov = iov; | 447 | i->iov = iov; |
443 | } | 448 | } |
444 | i->nr_segs = nr_segs; | 449 | i->nr_segs = nr_segs; |
@@ -558,7 +563,7 @@ static size_t copy_pipe_to_iter(const void *addr, size_t bytes, | |||
558 | size_t _copy_to_iter(const void *addr, size_t bytes, struct iov_iter *i) | 563 | size_t _copy_to_iter(const void *addr, size_t bytes, struct iov_iter *i) |
559 | { | 564 | { |
560 | const char *from = addr; | 565 | const char *from = addr; |
561 | if (unlikely(i->type & ITER_PIPE)) | 566 | if (unlikely(iov_iter_is_pipe(i))) |
562 | return copy_pipe_to_iter(addr, bytes, i); | 567 | return copy_pipe_to_iter(addr, bytes, i); |
563 | if (iter_is_iovec(i)) | 568 | if (iter_is_iovec(i)) |
564 | might_fault(); | 569 | might_fault(); |
@@ -658,7 +663,7 @@ size_t _copy_to_iter_mcsafe(const void *addr, size_t bytes, struct iov_iter *i) | |||
658 | const char *from = addr; | 663 | const char *from = addr; |
659 | unsigned long rem, curr_addr, s_addr = (unsigned long) addr; | 664 | unsigned long rem, curr_addr, s_addr = (unsigned long) addr; |
660 | 665 | ||
661 | if (unlikely(i->type & ITER_PIPE)) | 666 | if (unlikely(iov_iter_is_pipe(i))) |
662 | return copy_pipe_to_iter_mcsafe(addr, bytes, i); | 667 | return copy_pipe_to_iter_mcsafe(addr, bytes, i); |
663 | if (iter_is_iovec(i)) | 668 | if (iter_is_iovec(i)) |
664 | might_fault(); | 669 | might_fault(); |
@@ -692,7 +697,7 @@ EXPORT_SYMBOL_GPL(_copy_to_iter_mcsafe); | |||
692 | size_t _copy_from_iter(void *addr, size_t bytes, struct iov_iter *i) | 697 | size_t _copy_from_iter(void *addr, size_t bytes, struct iov_iter *i) |
693 | { | 698 | { |
694 | char *to = addr; | 699 | char *to = addr; |
695 | if (unlikely(i->type & ITER_PIPE)) { | 700 | if (unlikely(iov_iter_is_pipe(i))) { |
696 | WARN_ON(1); | 701 | WARN_ON(1); |
697 | return 0; | 702 | return 0; |
698 | } | 703 | } |
@@ -712,7 +717,7 @@ EXPORT_SYMBOL(_copy_from_iter); | |||
712 | bool _copy_from_iter_full(void *addr, size_t bytes, struct iov_iter *i) | 717 | bool _copy_from_iter_full(void *addr, size_t bytes, struct iov_iter *i) |
713 | { | 718 | { |
714 | char *to = addr; | 719 | char *to = addr; |
715 | if (unlikely(i->type & ITER_PIPE)) { | 720 | if (unlikely(iov_iter_is_pipe(i))) { |
716 | WARN_ON(1); | 721 | WARN_ON(1); |
717 | return false; | 722 | return false; |
718 | } | 723 | } |
@@ -739,7 +744,7 @@ EXPORT_SYMBOL(_copy_from_iter_full); | |||
739 | size_t _copy_from_iter_nocache(void *addr, size_t bytes, struct iov_iter *i) | 744 | size_t _copy_from_iter_nocache(void *addr, size_t bytes, struct iov_iter *i) |
740 | { | 745 | { |
741 | char *to = addr; | 746 | char *to = addr; |
742 | if (unlikely(i->type & ITER_PIPE)) { | 747 | if (unlikely(iov_iter_is_pipe(i))) { |
743 | WARN_ON(1); | 748 | WARN_ON(1); |
744 | return 0; | 749 | return 0; |
745 | } | 750 | } |
@@ -773,7 +778,7 @@ EXPORT_SYMBOL(_copy_from_iter_nocache); | |||
773 | size_t _copy_from_iter_flushcache(void *addr, size_t bytes, struct iov_iter *i) | 778 | size_t _copy_from_iter_flushcache(void *addr, size_t bytes, struct iov_iter *i) |
774 | { | 779 | { |
775 | char *to = addr; | 780 | char *to = addr; |
776 | if (unlikely(i->type & ITER_PIPE)) { | 781 | if (unlikely(iov_iter_is_pipe(i))) { |
777 | WARN_ON(1); | 782 | WARN_ON(1); |
778 | return 0; | 783 | return 0; |
779 | } | 784 | } |
@@ -794,7 +799,7 @@ EXPORT_SYMBOL_GPL(_copy_from_iter_flushcache); | |||
794 | bool _copy_from_iter_full_nocache(void *addr, size_t bytes, struct iov_iter *i) | 799 | bool _copy_from_iter_full_nocache(void *addr, size_t bytes, struct iov_iter *i) |
795 | { | 800 | { |
796 | char *to = addr; | 801 | char *to = addr; |
797 | if (unlikely(i->type & ITER_PIPE)) { | 802 | if (unlikely(iov_iter_is_pipe(i))) { |
798 | WARN_ON(1); | 803 | WARN_ON(1); |
799 | return false; | 804 | return false; |
800 | } | 805 | } |
@@ -836,7 +841,9 @@ size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes, | |||
836 | size_t wanted = copy_to_iter(kaddr + offset, bytes, i); | 841 | size_t wanted = copy_to_iter(kaddr + offset, bytes, i); |
837 | kunmap_atomic(kaddr); | 842 | kunmap_atomic(kaddr); |
838 | return wanted; | 843 | return wanted; |
839 | } else if (likely(!(i->type & ITER_PIPE))) | 844 | } else if (unlikely(iov_iter_is_discard(i))) |
845 | return bytes; | ||
846 | else if (likely(!iov_iter_is_pipe(i))) | ||
840 | return copy_page_to_iter_iovec(page, offset, bytes, i); | 847 | return copy_page_to_iter_iovec(page, offset, bytes, i); |
841 | else | 848 | else |
842 | return copy_page_to_iter_pipe(page, offset, bytes, i); | 849 | return copy_page_to_iter_pipe(page, offset, bytes, i); |
@@ -848,7 +855,7 @@ size_t copy_page_from_iter(struct page *page, size_t offset, size_t bytes, | |||
848 | { | 855 | { |
849 | if (unlikely(!page_copy_sane(page, offset, bytes))) | 856 | if (unlikely(!page_copy_sane(page, offset, bytes))) |
850 | return 0; | 857 | return 0; |
851 | if (unlikely(i->type & ITER_PIPE)) { | 858 | if (unlikely(iov_iter_is_pipe(i) || iov_iter_is_discard(i))) { |
852 | WARN_ON(1); | 859 | WARN_ON(1); |
853 | return 0; | 860 | return 0; |
854 | } | 861 | } |
@@ -888,7 +895,7 @@ static size_t pipe_zero(size_t bytes, struct iov_iter *i) | |||
888 | 895 | ||
889 | size_t iov_iter_zero(size_t bytes, struct iov_iter *i) | 896 | size_t iov_iter_zero(size_t bytes, struct iov_iter *i) |
890 | { | 897 | { |
891 | if (unlikely(i->type & ITER_PIPE)) | 898 | if (unlikely(iov_iter_is_pipe(i))) |
892 | return pipe_zero(bytes, i); | 899 | return pipe_zero(bytes, i); |
893 | iterate_and_advance(i, bytes, v, | 900 | iterate_and_advance(i, bytes, v, |
894 | clear_user(v.iov_base, v.iov_len), | 901 | clear_user(v.iov_base, v.iov_len), |
@@ -908,7 +915,7 @@ size_t iov_iter_copy_from_user_atomic(struct page *page, | |||
908 | kunmap_atomic(kaddr); | 915 | kunmap_atomic(kaddr); |
909 | return 0; | 916 | return 0; |
910 | } | 917 | } |
911 | if (unlikely(i->type & ITER_PIPE)) { | 918 | if (unlikely(iov_iter_is_pipe(i) || iov_iter_is_discard(i))) { |
912 | kunmap_atomic(kaddr); | 919 | kunmap_atomic(kaddr); |
913 | WARN_ON(1); | 920 | WARN_ON(1); |
914 | return 0; | 921 | return 0; |
@@ -972,10 +979,14 @@ static void pipe_advance(struct iov_iter *i, size_t size) | |||
972 | 979 | ||
973 | void iov_iter_advance(struct iov_iter *i, size_t size) | 980 | void iov_iter_advance(struct iov_iter *i, size_t size) |
974 | { | 981 | { |
975 | if (unlikely(i->type & ITER_PIPE)) { | 982 | if (unlikely(iov_iter_is_pipe(i))) { |
976 | pipe_advance(i, size); | 983 | pipe_advance(i, size); |
977 | return; | 984 | return; |
978 | } | 985 | } |
986 | if (unlikely(iov_iter_is_discard(i))) { | ||
987 | i->count -= size; | ||
988 | return; | ||
989 | } | ||
979 | iterate_and_advance(i, size, v, 0, 0, 0) | 990 | iterate_and_advance(i, size, v, 0, 0, 0) |
980 | } | 991 | } |
981 | EXPORT_SYMBOL(iov_iter_advance); | 992 | EXPORT_SYMBOL(iov_iter_advance); |
@@ -987,7 +998,7 @@ void iov_iter_revert(struct iov_iter *i, size_t unroll) | |||
987 | if (WARN_ON(unroll > MAX_RW_COUNT)) | 998 | if (WARN_ON(unroll > MAX_RW_COUNT)) |
988 | return; | 999 | return; |
989 | i->count += unroll; | 1000 | i->count += unroll; |
990 | if (unlikely(i->type & ITER_PIPE)) { | 1001 | if (unlikely(iov_iter_is_pipe(i))) { |
991 | struct pipe_inode_info *pipe = i->pipe; | 1002 | struct pipe_inode_info *pipe = i->pipe; |
992 | int idx = i->idx; | 1003 | int idx = i->idx; |
993 | size_t off = i->iov_offset; | 1004 | size_t off = i->iov_offset; |
@@ -1011,12 +1022,14 @@ void iov_iter_revert(struct iov_iter *i, size_t unroll) | |||
1011 | pipe_truncate(i); | 1022 | pipe_truncate(i); |
1012 | return; | 1023 | return; |
1013 | } | 1024 | } |
1025 | if (unlikely(iov_iter_is_discard(i))) | ||
1026 | return; | ||
1014 | if (unroll <= i->iov_offset) { | 1027 | if (unroll <= i->iov_offset) { |
1015 | i->iov_offset -= unroll; | 1028 | i->iov_offset -= unroll; |
1016 | return; | 1029 | return; |
1017 | } | 1030 | } |
1018 | unroll -= i->iov_offset; | 1031 | unroll -= i->iov_offset; |
1019 | if (i->type & ITER_BVEC) { | 1032 | if (iov_iter_is_bvec(i)) { |
1020 | const struct bio_vec *bvec = i->bvec; | 1033 | const struct bio_vec *bvec = i->bvec; |
1021 | while (1) { | 1034 | while (1) { |
1022 | size_t n = (--bvec)->bv_len; | 1035 | size_t n = (--bvec)->bv_len; |
@@ -1049,23 +1062,25 @@ EXPORT_SYMBOL(iov_iter_revert); | |||
1049 | */ | 1062 | */ |
1050 | size_t iov_iter_single_seg_count(const struct iov_iter *i) | 1063 | size_t iov_iter_single_seg_count(const struct iov_iter *i) |
1051 | { | 1064 | { |
1052 | if (unlikely(i->type & ITER_PIPE)) | 1065 | if (unlikely(iov_iter_is_pipe(i))) |
1053 | return i->count; // it is a silly place, anyway | 1066 | return i->count; // it is a silly place, anyway |
1054 | if (i->nr_segs == 1) | 1067 | if (i->nr_segs == 1) |
1055 | return i->count; | 1068 | return i->count; |
1056 | else if (i->type & ITER_BVEC) | 1069 | if (unlikely(iov_iter_is_discard(i))) |
1070 | return i->count; | ||
1071 | else if (iov_iter_is_bvec(i)) | ||
1057 | return min(i->count, i->bvec->bv_len - i->iov_offset); | 1072 | return min(i->count, i->bvec->bv_len - i->iov_offset); |
1058 | else | 1073 | else |
1059 | return min(i->count, i->iov->iov_len - i->iov_offset); | 1074 | return min(i->count, i->iov->iov_len - i->iov_offset); |
1060 | } | 1075 | } |
1061 | EXPORT_SYMBOL(iov_iter_single_seg_count); | 1076 | EXPORT_SYMBOL(iov_iter_single_seg_count); |
1062 | 1077 | ||
1063 | void iov_iter_kvec(struct iov_iter *i, int direction, | 1078 | void iov_iter_kvec(struct iov_iter *i, unsigned int direction, |
1064 | const struct kvec *kvec, unsigned long nr_segs, | 1079 | const struct kvec *kvec, unsigned long nr_segs, |
1065 | size_t count) | 1080 | size_t count) |
1066 | { | 1081 | { |
1067 | BUG_ON(!(direction & ITER_KVEC)); | 1082 | WARN_ON(direction & ~(READ | WRITE)); |
1068 | i->type = direction; | 1083 | i->type = ITER_KVEC | (direction & (READ | WRITE)); |
1069 | i->kvec = kvec; | 1084 | i->kvec = kvec; |
1070 | i->nr_segs = nr_segs; | 1085 | i->nr_segs = nr_segs; |
1071 | i->iov_offset = 0; | 1086 | i->iov_offset = 0; |
@@ -1073,12 +1088,12 @@ void iov_iter_kvec(struct iov_iter *i, int direction, | |||
1073 | } | 1088 | } |
1074 | EXPORT_SYMBOL(iov_iter_kvec); | 1089 | EXPORT_SYMBOL(iov_iter_kvec); |
1075 | 1090 | ||
1076 | void iov_iter_bvec(struct iov_iter *i, int direction, | 1091 | void iov_iter_bvec(struct iov_iter *i, unsigned int direction, |
1077 | const struct bio_vec *bvec, unsigned long nr_segs, | 1092 | const struct bio_vec *bvec, unsigned long nr_segs, |
1078 | size_t count) | 1093 | size_t count) |
1079 | { | 1094 | { |
1080 | BUG_ON(!(direction & ITER_BVEC)); | 1095 | WARN_ON(direction & ~(READ | WRITE)); |
1081 | i->type = direction; | 1096 | i->type = ITER_BVEC | (direction & (READ | WRITE)); |
1082 | i->bvec = bvec; | 1097 | i->bvec = bvec; |
1083 | i->nr_segs = nr_segs; | 1098 | i->nr_segs = nr_segs; |
1084 | i->iov_offset = 0; | 1099 | i->iov_offset = 0; |
@@ -1086,13 +1101,13 @@ void iov_iter_bvec(struct iov_iter *i, int direction, | |||
1086 | } | 1101 | } |
1087 | EXPORT_SYMBOL(iov_iter_bvec); | 1102 | EXPORT_SYMBOL(iov_iter_bvec); |
1088 | 1103 | ||
1089 | void iov_iter_pipe(struct iov_iter *i, int direction, | 1104 | void iov_iter_pipe(struct iov_iter *i, unsigned int direction, |
1090 | struct pipe_inode_info *pipe, | 1105 | struct pipe_inode_info *pipe, |
1091 | size_t count) | 1106 | size_t count) |
1092 | { | 1107 | { |
1093 | BUG_ON(direction != ITER_PIPE); | 1108 | BUG_ON(direction != READ); |
1094 | WARN_ON(pipe->nrbufs == pipe->buffers); | 1109 | WARN_ON(pipe->nrbufs == pipe->buffers); |
1095 | i->type = direction; | 1110 | i->type = ITER_PIPE | READ; |
1096 | i->pipe = pipe; | 1111 | i->pipe = pipe; |
1097 | i->idx = (pipe->curbuf + pipe->nrbufs) & (pipe->buffers - 1); | 1112 | i->idx = (pipe->curbuf + pipe->nrbufs) & (pipe->buffers - 1); |
1098 | i->iov_offset = 0; | 1113 | i->iov_offset = 0; |
@@ -1101,12 +1116,30 @@ void iov_iter_pipe(struct iov_iter *i, int direction, | |||
1101 | } | 1116 | } |
1102 | EXPORT_SYMBOL(iov_iter_pipe); | 1117 | EXPORT_SYMBOL(iov_iter_pipe); |
1103 | 1118 | ||
1119 | /** | ||
1120 | * iov_iter_discard - Initialise an I/O iterator that discards data | ||
1121 | * @i: The iterator to initialise. | ||
1122 | * @direction: The direction of the transfer. | ||
1123 | * @count: The size of the I/O buffer in bytes. | ||
1124 | * | ||
1125 | * Set up an I/O iterator that just discards everything that's written to it. | ||
1126 | * It's only available as a READ iterator. | ||
1127 | */ | ||
1128 | void iov_iter_discard(struct iov_iter *i, unsigned int direction, size_t count) | ||
1129 | { | ||
1130 | BUG_ON(direction != READ); | ||
1131 | i->type = ITER_DISCARD | READ; | ||
1132 | i->count = count; | ||
1133 | i->iov_offset = 0; | ||
1134 | } | ||
1135 | EXPORT_SYMBOL(iov_iter_discard); | ||
1136 | |||
1104 | unsigned long iov_iter_alignment(const struct iov_iter *i) | 1137 | unsigned long iov_iter_alignment(const struct iov_iter *i) |
1105 | { | 1138 | { |
1106 | unsigned long res = 0; | 1139 | unsigned long res = 0; |
1107 | size_t size = i->count; | 1140 | size_t size = i->count; |
1108 | 1141 | ||
1109 | if (unlikely(i->type & ITER_PIPE)) { | 1142 | if (unlikely(iov_iter_is_pipe(i))) { |
1110 | if (size && i->iov_offset && allocated(&i->pipe->bufs[i->idx])) | 1143 | if (size && i->iov_offset && allocated(&i->pipe->bufs[i->idx])) |
1111 | return size | i->iov_offset; | 1144 | return size | i->iov_offset; |
1112 | return size; | 1145 | return size; |
@@ -1125,7 +1158,7 @@ unsigned long iov_iter_gap_alignment(const struct iov_iter *i) | |||
1125 | unsigned long res = 0; | 1158 | unsigned long res = 0; |
1126 | size_t size = i->count; | 1159 | size_t size = i->count; |
1127 | 1160 | ||
1128 | if (unlikely(i->type & ITER_PIPE)) { | 1161 | if (unlikely(iov_iter_is_pipe(i) || iov_iter_is_discard(i))) { |
1129 | WARN_ON(1); | 1162 | WARN_ON(1); |
1130 | return ~0U; | 1163 | return ~0U; |
1131 | } | 1164 | } |
@@ -1193,8 +1226,11 @@ ssize_t iov_iter_get_pages(struct iov_iter *i, | |||
1193 | if (maxsize > i->count) | 1226 | if (maxsize > i->count) |
1194 | maxsize = i->count; | 1227 | maxsize = i->count; |
1195 | 1228 | ||
1196 | if (unlikely(i->type & ITER_PIPE)) | 1229 | if (unlikely(iov_iter_is_pipe(i))) |
1197 | return pipe_get_pages(i, pages, maxsize, maxpages, start); | 1230 | return pipe_get_pages(i, pages, maxsize, maxpages, start); |
1231 | if (unlikely(iov_iter_is_discard(i))) | ||
1232 | return -EFAULT; | ||
1233 | |||
1198 | iterate_all_kinds(i, maxsize, v, ({ | 1234 | iterate_all_kinds(i, maxsize, v, ({ |
1199 | unsigned long addr = (unsigned long)v.iov_base; | 1235 | unsigned long addr = (unsigned long)v.iov_base; |
1200 | size_t len = v.iov_len + (*start = addr & (PAGE_SIZE - 1)); | 1236 | size_t len = v.iov_len + (*start = addr & (PAGE_SIZE - 1)); |
@@ -1205,7 +1241,7 @@ ssize_t iov_iter_get_pages(struct iov_iter *i, | |||
1205 | len = maxpages * PAGE_SIZE; | 1241 | len = maxpages * PAGE_SIZE; |
1206 | addr &= ~(PAGE_SIZE - 1); | 1242 | addr &= ~(PAGE_SIZE - 1); |
1207 | n = DIV_ROUND_UP(len, PAGE_SIZE); | 1243 | n = DIV_ROUND_UP(len, PAGE_SIZE); |
1208 | res = get_user_pages_fast(addr, n, (i->type & WRITE) != WRITE, pages); | 1244 | res = get_user_pages_fast(addr, n, iov_iter_rw(i) != WRITE, pages); |
1209 | if (unlikely(res < 0)) | 1245 | if (unlikely(res < 0)) |
1210 | return res; | 1246 | return res; |
1211 | return (res == n ? len : res * PAGE_SIZE) - *start; | 1247 | return (res == n ? len : res * PAGE_SIZE) - *start; |
@@ -1270,8 +1306,11 @@ ssize_t iov_iter_get_pages_alloc(struct iov_iter *i, | |||
1270 | if (maxsize > i->count) | 1306 | if (maxsize > i->count) |
1271 | maxsize = i->count; | 1307 | maxsize = i->count; |
1272 | 1308 | ||
1273 | if (unlikely(i->type & ITER_PIPE)) | 1309 | if (unlikely(iov_iter_is_pipe(i))) |
1274 | return pipe_get_pages_alloc(i, pages, maxsize, start); | 1310 | return pipe_get_pages_alloc(i, pages, maxsize, start); |
1311 | if (unlikely(iov_iter_is_discard(i))) | ||
1312 | return -EFAULT; | ||
1313 | |||
1275 | iterate_all_kinds(i, maxsize, v, ({ | 1314 | iterate_all_kinds(i, maxsize, v, ({ |
1276 | unsigned long addr = (unsigned long)v.iov_base; | 1315 | unsigned long addr = (unsigned long)v.iov_base; |
1277 | size_t len = v.iov_len + (*start = addr & (PAGE_SIZE - 1)); | 1316 | size_t len = v.iov_len + (*start = addr & (PAGE_SIZE - 1)); |
@@ -1283,7 +1322,7 @@ ssize_t iov_iter_get_pages_alloc(struct iov_iter *i, | |||
1283 | p = get_pages_array(n); | 1322 | p = get_pages_array(n); |
1284 | if (!p) | 1323 | if (!p) |
1285 | return -ENOMEM; | 1324 | return -ENOMEM; |
1286 | res = get_user_pages_fast(addr, n, (i->type & WRITE) != WRITE, p); | 1325 | res = get_user_pages_fast(addr, n, iov_iter_rw(i) != WRITE, p); |
1287 | if (unlikely(res < 0)) { | 1326 | if (unlikely(res < 0)) { |
1288 | kvfree(p); | 1327 | kvfree(p); |
1289 | return res; | 1328 | return res; |
@@ -1313,7 +1352,7 @@ size_t csum_and_copy_from_iter(void *addr, size_t bytes, __wsum *csum, | |||
1313 | __wsum sum, next; | 1352 | __wsum sum, next; |
1314 | size_t off = 0; | 1353 | size_t off = 0; |
1315 | sum = *csum; | 1354 | sum = *csum; |
1316 | if (unlikely(i->type & ITER_PIPE)) { | 1355 | if (unlikely(iov_iter_is_pipe(i) || iov_iter_is_discard(i))) { |
1317 | WARN_ON(1); | 1356 | WARN_ON(1); |
1318 | return 0; | 1357 | return 0; |
1319 | } | 1358 | } |
@@ -1355,7 +1394,7 @@ bool csum_and_copy_from_iter_full(void *addr, size_t bytes, __wsum *csum, | |||
1355 | __wsum sum, next; | 1394 | __wsum sum, next; |
1356 | size_t off = 0; | 1395 | size_t off = 0; |
1357 | sum = *csum; | 1396 | sum = *csum; |
1358 | if (unlikely(i->type & ITER_PIPE)) { | 1397 | if (unlikely(iov_iter_is_pipe(i) || iov_iter_is_discard(i))) { |
1359 | WARN_ON(1); | 1398 | WARN_ON(1); |
1360 | return false; | 1399 | return false; |
1361 | } | 1400 | } |
@@ -1400,7 +1439,7 @@ size_t csum_and_copy_to_iter(const void *addr, size_t bytes, __wsum *csum, | |||
1400 | __wsum sum, next; | 1439 | __wsum sum, next; |
1401 | size_t off = 0; | 1440 | size_t off = 0; |
1402 | sum = *csum; | 1441 | sum = *csum; |
1403 | if (unlikely(i->type & ITER_PIPE)) { | 1442 | if (unlikely(iov_iter_is_pipe(i) || iov_iter_is_discard(i))) { |
1404 | WARN_ON(1); /* for now */ | 1443 | WARN_ON(1); /* for now */ |
1405 | return 0; | 1444 | return 0; |
1406 | } | 1445 | } |
@@ -1442,8 +1481,10 @@ int iov_iter_npages(const struct iov_iter *i, int maxpages) | |||
1442 | 1481 | ||
1443 | if (!size) | 1482 | if (!size) |
1444 | return 0; | 1483 | return 0; |
1484 | if (unlikely(iov_iter_is_discard(i))) | ||
1485 | return 0; | ||
1445 | 1486 | ||
1446 | if (unlikely(i->type & ITER_PIPE)) { | 1487 | if (unlikely(iov_iter_is_pipe(i))) { |
1447 | struct pipe_inode_info *pipe = i->pipe; | 1488 | struct pipe_inode_info *pipe = i->pipe; |
1448 | size_t off; | 1489 | size_t off; |
1449 | int idx; | 1490 | int idx; |
@@ -1481,11 +1522,13 @@ EXPORT_SYMBOL(iov_iter_npages); | |||
1481 | const void *dup_iter(struct iov_iter *new, struct iov_iter *old, gfp_t flags) | 1522 | const void *dup_iter(struct iov_iter *new, struct iov_iter *old, gfp_t flags) |
1482 | { | 1523 | { |
1483 | *new = *old; | 1524 | *new = *old; |
1484 | if (unlikely(new->type & ITER_PIPE)) { | 1525 | if (unlikely(iov_iter_is_pipe(new))) { |
1485 | WARN_ON(1); | 1526 | WARN_ON(1); |
1486 | return NULL; | 1527 | return NULL; |
1487 | } | 1528 | } |
1488 | if (new->type & ITER_BVEC) | 1529 | if (unlikely(iov_iter_is_discard(new))) |
1530 | return NULL; | ||
1531 | if (iov_iter_is_bvec(new)) | ||
1489 | return new->bvec = kmemdup(new->bvec, | 1532 | return new->bvec = kmemdup(new->bvec, |
1490 | new->nr_segs * sizeof(struct bio_vec), | 1533 | new->nr_segs * sizeof(struct bio_vec), |
1491 | flags); | 1534 | flags); |