diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2013-05-16 19:35:21 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2013-05-19 20:54:22 -0400 |
commit | d2f83e9078b8114e3b9d09082856c1aac299aa37 (patch) | |
tree | 707f0d810d28e000eb3f9a775be880687dde1030 /lib/iovec.c | |
parent | d5fe85af85367d5892e4308f596de4e2a5fb9017 (diff) |
Hoist memcpy_fromiovec/memcpy_toiovec into lib/
ERROR: "memcpy_fromiovec" [drivers/vhost/vhost_scsi.ko] undefined!
That function is only present with CONFIG_NET. Turns out that
crypto/algif_skcipher.c also uses that outside net, but it actually
needs sockets anyway.
In addition, commit 6d4f0139d642c45411a47879325891ce2a7c164a added
CONFIG_NET dependency to CONFIG_VMCI for memcpy_toiovec, so hoist
that function and revert that commit too.
socket.h already includes uio.h, so no callers need updating; trying
only broke things fo x86_64 randconfig (thanks Fengguang!).
Reported-by: Randy Dunlap <rdunlap@infradead.org>
Acked-by: David S. Miller <davem@davemloft.net>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'lib/iovec.c')
-rw-r--r-- | lib/iovec.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/lib/iovec.c b/lib/iovec.c new file mode 100644 index 000000000000..454baa88bf27 --- /dev/null +++ b/lib/iovec.c | |||
@@ -0,0 +1,53 @@ | |||
1 | #include <linux/uaccess.h> | ||
2 | #include <linux/export.h> | ||
3 | #include <linux/uio.h> | ||
4 | |||
5 | /* | ||
6 | * Copy iovec to kernel. Returns -EFAULT on error. | ||
7 | * | ||
8 | * Note: this modifies the original iovec. | ||
9 | */ | ||
10 | |||
11 | int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len) | ||
12 | { | ||
13 | while (len > 0) { | ||
14 | if (iov->iov_len) { | ||
15 | int copy = min_t(unsigned int, len, iov->iov_len); | ||
16 | if (copy_from_user(kdata, iov->iov_base, copy)) | ||
17 | return -EFAULT; | ||
18 | len -= copy; | ||
19 | kdata += copy; | ||
20 | iov->iov_base += copy; | ||
21 | iov->iov_len -= copy; | ||
22 | } | ||
23 | iov++; | ||
24 | } | ||
25 | |||
26 | return 0; | ||
27 | } | ||
28 | EXPORT_SYMBOL(memcpy_fromiovec); | ||
29 | |||
30 | /* | ||
31 | * Copy kernel to iovec. Returns -EFAULT on error. | ||
32 | * | ||
33 | * Note: this modifies the original iovec. | ||
34 | */ | ||
35 | |||
36 | int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len) | ||
37 | { | ||
38 | while (len > 0) { | ||
39 | if (iov->iov_len) { | ||
40 | int copy = min_t(unsigned int, iov->iov_len, len); | ||
41 | if (copy_to_user(iov->iov_base, kdata, copy)) | ||
42 | return -EFAULT; | ||
43 | kdata += copy; | ||
44 | len -= copy; | ||
45 | iov->iov_len -= copy; | ||
46 | iov->iov_base += copy; | ||
47 | } | ||
48 | iov++; | ||
49 | } | ||
50 | |||
51 | return 0; | ||
52 | } | ||
53 | EXPORT_SYMBOL(memcpy_toiovec); | ||