aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVegard Nossum <vegard.nossum@oracle.com>2016-10-08 05:18:07 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2016-10-14 20:00:34 -0400
commitffecee4f2442bb8cb6b34c3335fef4eb50c22fdd (patch)
tree53d6e7bcb5ff21f6f72d12d905b5173b35c2987a
parentde34f4da7f62ff59ac6e1ef320b0fcfa3296fce3 (diff)
iov_iter: kernel-doc import_iovec() and rw_copy_check_uvector()
Both import_iovec() and rw_copy_check_uvector() take an array (typically small and on-stack) which is used to hold an iovec array copy from userspace. This is to avoid an expensive memory allocation in the fast path (i.e. few iovec elements). The caller may have to check whether these functions actually used the provided buffer or allocated a new one -- but this differs between the too. Let's just add a kernel doc to clarify what the semantics are for each function. Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/read_write.c29
-rw-r--r--lib/iov_iter.c22
2 files changed, 51 insertions, 0 deletions
diff --git a/fs/read_write.c b/fs/read_write.c
index 66215a7b17cf..190e0d362581 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -730,6 +730,35 @@ static ssize_t do_loop_readv_writev(struct file *filp, struct iov_iter *iter,
730/* A write operation does a read from user space and vice versa */ 730/* A write operation does a read from user space and vice versa */
731#define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ) 731#define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ)
732 732
733/**
734 * rw_copy_check_uvector() - Copy an array of &struct iovec from userspace
735 * into the kernel and check that it is valid.
736 *
737 * @type: One of %CHECK_IOVEC_ONLY, %READ, or %WRITE.
738 * @uvector: Pointer to the userspace array.
739 * @nr_segs: Number of elements in userspace array.
740 * @fast_segs: Number of elements in @fast_pointer.
741 * @fast_pointer: Pointer to (usually small on-stack) kernel array.
742 * @ret_pointer: (output parameter) Pointer to a variable that will point to
743 * either @fast_pointer, a newly allocated kernel array, or NULL,
744 * depending on which array was used.
745 *
746 * This function copies an array of &struct iovec of @nr_segs from
747 * userspace into the kernel and checks that each element is valid (e.g.
748 * it does not point to a kernel address or cause overflow by being too
749 * large, etc.).
750 *
751 * As an optimization, the caller may provide a pointer to a small
752 * on-stack array in @fast_pointer, typically %UIO_FASTIOV elements long
753 * (the size of this array, or 0 if unused, should be given in @fast_segs).
754 *
755 * @ret_pointer will always point to the array that was used, so the
756 * caller must take care not to call kfree() on it e.g. in case the
757 * @fast_pointer array was used and it was allocated on the stack.
758 *
759 * Return: The total number of bytes covered by the iovec array on success
760 * or a negative error code on error.
761 */
733ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, 762ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
734 unsigned long nr_segs, unsigned long fast_segs, 763 unsigned long nr_segs, unsigned long fast_segs,
735 struct iovec *fast_pointer, 764 struct iovec *fast_pointer,
diff --git a/lib/iov_iter.c b/lib/iov_iter.c
index 7312e7784611..f0c7f1481bae 100644
--- a/lib/iov_iter.c
+++ b/lib/iov_iter.c
@@ -1139,6 +1139,28 @@ const void *dup_iter(struct iov_iter *new, struct iov_iter *old, gfp_t flags)
1139} 1139}
1140EXPORT_SYMBOL(dup_iter); 1140EXPORT_SYMBOL(dup_iter);
1141 1141
1142/**
1143 * import_iovec() - Copy an array of &struct iovec from userspace
1144 * into the kernel, check that it is valid, and initialize a new
1145 * &struct iov_iter iterator to access it.
1146 *
1147 * @type: One of %READ or %WRITE.
1148 * @uvector: Pointer to the userspace array.
1149 * @nr_segs: Number of elements in userspace array.
1150 * @fast_segs: Number of elements in @iov.
1151 * @iov: (input and output parameter) Pointer to pointer to (usually small
1152 * on-stack) kernel array.
1153 * @i: Pointer to iterator that will be initialized on success.
1154 *
1155 * If the array pointed to by *@iov is large enough to hold all @nr_segs,
1156 * then this function places %NULL in *@iov on return. Otherwise, a new
1157 * array will be allocated and the result placed in *@iov. This means that
1158 * the caller may call kfree() on *@iov regardless of whether the small
1159 * on-stack array was used or not (and regardless of whether this function
1160 * returns an error or not).
1161 *
1162 * Return: 0 on success or negative error code on error.
1163 */
1142int import_iovec(int type, const struct iovec __user * uvector, 1164int import_iovec(int type, const struct iovec __user * uvector,
1143 unsigned nr_segs, unsigned fast_segs, 1165 unsigned nr_segs, unsigned fast_segs,
1144 struct iovec **iov, struct iov_iter *i) 1166 struct iovec **iov, struct iov_iter *i)