On 30/01/2015 09:12, Nicholas A. Bellinger wrote:
> From: Nicholas Bellinger <[email protected]>
>
> This patch adds a new memcpy_fromiovec_out() library function which modifies
> the passed *iov following memcpy_fromiovec(), but also returns the next
> current
> iovec pointer via **iov_out.
>
> This is useful for vhost ANY_LAYOUT support when guests are allowed to
> generate
> incoming virtio request headers combined with subsequent SGL payloads into a
> single iovec.
>
> Cc: Michael S. Tsirkin <[email protected]>
> Cc: Paolo Bonzini <[email protected]>
> Signed-off-by: Nicholas Bellinger <[email protected]>
> ---
> include/linux/uio.h | 2 ++
> lib/iovec.c | 27 +++++++++++++++++++++++++++
> 2 files changed, 29 insertions(+)
>
> diff --git a/include/linux/uio.h b/include/linux/uio.h
> index 1c5e453..3e4473d 100644
> --- a/include/linux/uio.h
> +++ b/include/linux/uio.h
> @@ -136,6 +136,8 @@ size_t csum_and_copy_to_iter(void *addr, size_t bytes,
> __wsum *csum, struct iov_
> size_t csum_and_copy_from_iter(void *addr, size_t bytes, __wsum *csum,
> struct iov_iter *i);
>
> int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
> +int memcpy_fromiovec_out(unsigned char *kdata, struct iovec *iov,
> + struct iovec **iov_out, int len);
> int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
> int offset, int len);
> int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata,
> diff --git a/lib/iovec.c b/lib/iovec.c
> index 2d99cb4..6a813dd 100644
> --- a/lib/iovec.c
> +++ b/lib/iovec.c
> @@ -28,6 +28,33 @@ int memcpy_fromiovec(unsigned char *kdata, struct iovec
> *iov, int len)
> EXPORT_SYMBOL(memcpy_fromiovec);
>
> /*
> + * Copy iovec to kernel, saving the current iov to *iov_out.
> + * Returns -EFAULT on error.
Perhaps document that iov is modified, zeroing everything in [iov,
*iov_out) and possibly removing the front of *iov_out?
Paolo
> + */
> +
> +int memcpy_fromiovec_out(unsigned char *kdata, struct iovec *iov,
> + struct iovec **iov_out, int len)
> +{
> + while (len > 0) {
> + if (iov->iov_len) {
> + int copy = min_t(unsigned int, len, iov->iov_len);
> + if (copy_from_user(kdata, iov->iov_base, copy))
> + return -EFAULT;
> + len -= copy;
> + kdata += copy;
> + iov->iov_base += copy;
> + iov->iov_len -= copy;
> + }
> + if (!iov->iov_len)
> + iov++;
> + }
> + *iov_out = iov;
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(memcpy_fromiovec_out);
> +
> +/*
> * Copy kernel to iovec. Returns -EFAULT on error.
> */
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html