diff options
-rw-r--r-- | include/linux/uio.h | 1 | ||||
-rw-r--r-- | lib/iov_iter.c | 26 |
2 files changed, 27 insertions, 0 deletions
diff --git a/include/linux/uio.h b/include/linux/uio.h index 71880299ed48..a69ed25af07f 100644 --- a/include/linux/uio.h +++ b/include/linux/uio.h | |||
@@ -76,6 +76,7 @@ size_t iov_iter_copy_from_user_atomic(struct page *page, | |||
76 | struct iov_iter *i, unsigned long offset, size_t bytes); | 76 | struct iov_iter *i, unsigned long offset, size_t bytes); |
77 | void iov_iter_advance(struct iov_iter *i, size_t bytes); | 77 | void iov_iter_advance(struct iov_iter *i, size_t bytes); |
78 | int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes); | 78 | int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes); |
79 | int iov_iter_fault_in_multipages_readable(struct iov_iter *i, size_t bytes); | ||
79 | size_t iov_iter_single_seg_count(const struct iov_iter *i); | 80 | size_t iov_iter_single_seg_count(const struct iov_iter *i); |
80 | size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes, | 81 | size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes, |
81 | struct iov_iter *i); | 82 | struct iov_iter *i); |
diff --git a/lib/iov_iter.c b/lib/iov_iter.c index 9d96e283520c..b80f84376b91 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c | |||
@@ -317,6 +317,32 @@ int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes) | |||
317 | } | 317 | } |
318 | EXPORT_SYMBOL(iov_iter_fault_in_readable); | 318 | EXPORT_SYMBOL(iov_iter_fault_in_readable); |
319 | 319 | ||
320 | /* | ||
321 | * Fault in one or more iovecs of the given iov_iter, to a maximum length of | ||
322 | * bytes. For each iovec, fault in each page that constitutes the iovec. | ||
323 | * | ||
324 | * Return 0 on success, or non-zero if the memory could not be accessed (i.e. | ||
325 | * because it is an invalid address). | ||
326 | */ | ||
327 | int iov_iter_fault_in_multipages_readable(struct iov_iter *i, size_t bytes) | ||
328 | { | ||
329 | size_t skip = i->iov_offset; | ||
330 | const struct iovec *iov; | ||
331 | int err; | ||
332 | struct iovec v; | ||
333 | |||
334 | if (!(i->type & (ITER_BVEC|ITER_KVEC))) { | ||
335 | iterate_iovec(i, bytes, v, iov, skip, ({ | ||
336 | err = fault_in_multipages_readable(v.iov_base, | ||
337 | v.iov_len); | ||
338 | if (unlikely(err)) | ||
339 | return err; | ||
340 | 0;})) | ||
341 | } | ||
342 | return 0; | ||
343 | } | ||
344 | EXPORT_SYMBOL(iov_iter_fault_in_multipages_readable); | ||
345 | |||
320 | void iov_iter_init(struct iov_iter *i, int direction, | 346 | void iov_iter_init(struct iov_iter *i, int direction, |
321 | const struct iovec *iov, unsigned long nr_segs, | 347 | const struct iovec *iov, unsigned long nr_segs, |
322 | size_t count) | 348 | size_t count) |