On 06/19/14 11:22, Michael S. Tsirkin wrote:
> ERROR: "memcpy_fromiovecend" [drivers/vhost/vhost_scsi.ko] undefined!
> 
> commit 9f977ef7b671f6169eca78bf40f230fe84b7c7e5
>     vhost-scsi: Include prot_bytes into expected data transfer length
> in target-pending makes drivers/vhost/scsi.c call memcpy_fromiovecend().
> This function is not available when CONFIG_NET is not enabled.
> 
> socket.h already includes uio.h, so no callers need updating.
> 
> Reported-by: Randy Dunlap <rdun...@infradead.org>
> Cc: Stephen Rothwell <s...@canb.auug.org.au>
> Cc: "David S. Miller" <da...@davemloft.net>
> Signed-off-by: Michael S. Tsirkin <m...@redhat.com>

Acked-by: Randy Dunlap <rdun...@infradead.org> [build-tested]

Thanks.

> ---
> 
> David, could you please ack merging this through
> target-pending to avoid dependency issues?
> 
> Thanks!
> 
>  include/linux/socket.h |  4 ----
>  include/linux/uio.h    |  4 ++++
>  lib/iovec.c            | 55 
> ++++++++++++++++++++++++++++++++++++++++++++++++++
>  net/core/iovec.c       | 55 
> --------------------------------------------------
>  4 files changed, 59 insertions(+), 59 deletions(-)
> 
> diff --git a/include/linux/socket.h b/include/linux/socket.h
> index 8e98297..ec538fc 100644
> --- a/include/linux/socket.h
> +++ b/include/linux/socket.h
> @@ -305,8 +305,6 @@ struct ucred {
>  /* IPX options */
>  #define IPX_TYPE     1
>  
> -extern int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
> -                            int offset, int len);
>  extern int csum_partial_copy_fromiovecend(unsigned char *kdata, 
>                                         struct iovec *iov, 
>                                         int offset, 
> @@ -315,8 +313,6 @@ extern unsigned long iov_pages(const struct iovec *iov, 
> int offset,
>                              unsigned long nr_segs);
>  
>  extern int verify_iovec(struct msghdr *m, struct iovec *iov, struct 
> sockaddr_storage *address, int mode);
> -extern int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata,
> -                          int offset, int len);
>  extern int move_addr_to_kernel(void __user *uaddr, int ulen, struct 
> sockaddr_storage *kaddr);
>  extern int put_cmsg(struct msghdr*, int level, int type, int len, void 
> *data);
>  
> diff --git a/include/linux/uio.h b/include/linux/uio.h
> index 199bcc3..8a4709a 100644
> --- a/include/linux/uio.h
> +++ b/include/linux/uio.h
> @@ -89,5 +89,9 @@ static inline size_t iov_iter_count(struct iov_iter *i)
>  
>  int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
>  int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, 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,
> +                   int offset, int len);
>  
>  #endif
> diff --git a/lib/iovec.c b/lib/iovec.c
> index 454baa8..7a7c2da 100644
> --- a/lib/iovec.c
> +++ b/lib/iovec.c
> @@ -51,3 +51,58 @@ int memcpy_toiovec(struct iovec *iov, unsigned char 
> *kdata, int len)
>       return 0;
>  }
>  EXPORT_SYMBOL(memcpy_toiovec);
> +
> +/*
> + *   Copy kernel to iovec. Returns -EFAULT on error.
> + */
> +
> +int memcpy_toiovecend(const struct iovec *iov, unsigned char *kdata,
> +                   int offset, int len)
> +{
> +     int copy;
> +     for (; len > 0; ++iov) {
> +             /* Skip over the finished iovecs */
> +             if (unlikely(offset >= iov->iov_len)) {
> +                     offset -= iov->iov_len;
> +                     continue;
> +             }
> +             copy = min_t(unsigned int, iov->iov_len - offset, len);
> +             if (copy_to_user(iov->iov_base + offset, kdata, copy))
> +                     return -EFAULT;
> +             offset = 0;
> +             kdata += copy;
> +             len -= copy;
> +     }
> +
> +     return 0;
> +}
> +EXPORT_SYMBOL(memcpy_toiovecend);
> +
> +/*
> + *   Copy iovec to kernel. Returns -EFAULT on error.
> + */
> +
> +int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
> +                     int offset, int len)
> +{
> +     /* Skip over the finished iovecs */
> +     while (offset >= iov->iov_len) {
> +             offset -= iov->iov_len;
> +             iov++;
> +     }
> +
> +     while (len > 0) {
> +             u8 __user *base = iov->iov_base + offset;
> +             int copy = min_t(unsigned int, len, iov->iov_len - offset);
> +
> +             offset = 0;
> +             if (copy_from_user(kdata, base, copy))
> +                     return -EFAULT;
> +             len -= copy;
> +             kdata += copy;
> +             iov++;
> +     }
> +
> +     return 0;
> +}
> +EXPORT_SYMBOL(memcpy_fromiovecend);
> diff --git a/net/core/iovec.c b/net/core/iovec.c
> index b618694..827dd6b 100644
> --- a/net/core/iovec.c
> +++ b/net/core/iovec.c
> @@ -75,61 +75,6 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, 
> struct sockaddr_storage *a
>  }
>  
>  /*
> - *   Copy kernel to iovec. Returns -EFAULT on error.
> - */
> -
> -int memcpy_toiovecend(const struct iovec *iov, unsigned char *kdata,
> -                   int offset, int len)
> -{
> -     int copy;
> -     for (; len > 0; ++iov) {
> -             /* Skip over the finished iovecs */
> -             if (unlikely(offset >= iov->iov_len)) {
> -                     offset -= iov->iov_len;
> -                     continue;
> -             }
> -             copy = min_t(unsigned int, iov->iov_len - offset, len);
> -             if (copy_to_user(iov->iov_base + offset, kdata, copy))
> -                     return -EFAULT;
> -             offset = 0;
> -             kdata += copy;
> -             len -= copy;
> -     }
> -
> -     return 0;
> -}
> -EXPORT_SYMBOL(memcpy_toiovecend);
> -
> -/*
> - *   Copy iovec to kernel. Returns -EFAULT on error.
> - */
> -
> -int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
> -                     int offset, int len)
> -{
> -     /* Skip over the finished iovecs */
> -     while (offset >= iov->iov_len) {
> -             offset -= iov->iov_len;
> -             iov++;
> -     }
> -
> -     while (len > 0) {
> -             u8 __user *base = iov->iov_base + offset;
> -             int copy = min_t(unsigned int, len, iov->iov_len - offset);
> -
> -             offset = 0;
> -             if (copy_from_user(kdata, base, copy))
> -                     return -EFAULT;
> -             len -= copy;
> -             kdata += copy;
> -             iov++;
> -     }
> -
> -     return 0;
> -}
> -EXPORT_SYMBOL(memcpy_fromiovecend);
> -
> -/*
>   *   And now for the all-in-one: copy and checksum from a user iovec
>   *   directly to a datagram
>   *   Calls to csum_partial but the last must be in 32 bit chunks
> 


-- 
~Randy
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to