diff options
author | Michael S. Tsirkin <mst@redhat.com> | 2014-06-19 14:22:56 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-06-27 14:47:58 -0400 |
commit | ac5ccdba3a1659b3517e7e99ef7d35a6a2d77cf4 (patch) | |
tree | cbbec5559a3cb50e47c73494a9f256155a284efe /lib/iovec.c | |
parent | 97c99b47ac58bacb7c09e1f47d5d184434f6b06a (diff) |
iovec: move memcpy_from/toiovecend to lib/iovec.c
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 <rdunlap@infradead.org>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Cc: "David S. Miller" <davem@davemloft.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'lib/iovec.c')
-rw-r--r-- | lib/iovec.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/lib/iovec.c b/lib/iovec.c index 454baa88bf27..7a7c2da4cddf 100644 --- a/lib/iovec.c +++ b/lib/iovec.c | |||
@@ -51,3 +51,58 @@ int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len) | |||
51 | return 0; | 51 | return 0; |
52 | } | 52 | } |
53 | EXPORT_SYMBOL(memcpy_toiovec); | 53 | EXPORT_SYMBOL(memcpy_toiovec); |
54 | |||
55 | /* | ||
56 | * Copy kernel to iovec. Returns -EFAULT on error. | ||
57 | */ | ||
58 | |||
59 | int memcpy_toiovecend(const struct iovec *iov, unsigned char *kdata, | ||
60 | int offset, int len) | ||
61 | { | ||
62 | int copy; | ||
63 | for (; len > 0; ++iov) { | ||
64 | /* Skip over the finished iovecs */ | ||
65 | if (unlikely(offset >= iov->iov_len)) { | ||
66 | offset -= iov->iov_len; | ||
67 | continue; | ||
68 | } | ||
69 | copy = min_t(unsigned int, iov->iov_len - offset, len); | ||
70 | if (copy_to_user(iov->iov_base + offset, kdata, copy)) | ||
71 | return -EFAULT; | ||
72 | offset = 0; | ||
73 | kdata += copy; | ||
74 | len -= copy; | ||
75 | } | ||
76 | |||
77 | return 0; | ||
78 | } | ||
79 | EXPORT_SYMBOL(memcpy_toiovecend); | ||
80 | |||
81 | /* | ||
82 | * Copy iovec to kernel. Returns -EFAULT on error. | ||
83 | */ | ||
84 | |||
85 | int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov, | ||
86 | int offset, int len) | ||
87 | { | ||
88 | /* Skip over the finished iovecs */ | ||
89 | while (offset >= iov->iov_len) { | ||
90 | offset -= iov->iov_len; | ||
91 | iov++; | ||
92 | } | ||
93 | |||
94 | while (len > 0) { | ||
95 | u8 __user *base = iov->iov_base + offset; | ||
96 | int copy = min_t(unsigned int, len, iov->iov_len - offset); | ||
97 | |||
98 | offset = 0; | ||
99 | if (copy_from_user(kdata, base, copy)) | ||
100 | return -EFAULT; | ||
101 | len -= copy; | ||
102 | kdata += copy; | ||
103 | iov++; | ||
104 | } | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | EXPORT_SYMBOL(memcpy_fromiovecend); | ||