|  | #include <linux/uaccess.h> | 
|  | #include <linux/export.h> | 
|  | #include <linux/uio.h> | 
|  |  | 
|  | /* | 
|  | *	Copy iovec to kernel. Returns -EFAULT on error. | 
|  | * | 
|  | *	Note: this modifies the original iovec. | 
|  | */ | 
|  |  | 
|  | int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, 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; | 
|  | } | 
|  | iov++; | 
|  | } | 
|  |  | 
|  | return 0; | 
|  | } | 
|  | EXPORT_SYMBOL(memcpy_fromiovec); | 
|  |  | 
|  | /* | 
|  | *	Copy kernel to iovec. Returns -EFAULT on error. | 
|  | * | 
|  | *	Note: this modifies the original iovec. | 
|  | */ | 
|  |  | 
|  | int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len) | 
|  | { | 
|  | while (len > 0) { | 
|  | if (iov->iov_len) { | 
|  | int copy = min_t(unsigned int, iov->iov_len, len); | 
|  | if (copy_to_user(iov->iov_base, kdata, copy)) | 
|  | return -EFAULT; | 
|  | kdata += copy; | 
|  | len -= copy; | 
|  | iov->iov_len -= copy; | 
|  | iov->iov_base += copy; | 
|  | } | 
|  | iov++; | 
|  | } | 
|  |  | 
|  | return 0; | 
|  | } | 
|  | EXPORT_SYMBOL(memcpy_toiovec); |