|
@@ -31,6 +31,7 @@
|
|
|
#include <linux/security.h>
|
|
|
#include <linux/gfp.h>
|
|
|
#include <linux/socket.h>
|
|
|
+#include <linux/compat.h>
|
|
|
|
|
|
/*
|
|
|
* Attempt to steal a page from a pipe buffer. This should perhaps go into
|
|
@@ -1688,6 +1689,27 @@ SYSCALL_DEFINE4(vmsplice, int, fd, const struct iovec __user *, iov,
|
|
|
return error;
|
|
|
}
|
|
|
|
|
|
+#ifdef CONFIG_COMPAT
|
|
|
+COMPAT_SYSCALL_DEFINE4(vmsplice, int, fd, const struct compat_iovec __user *, iov32,
|
|
|
+ unsigned int, nr_segs, unsigned int, flags)
|
|
|
+{
|
|
|
+ unsigned i;
|
|
|
+ struct iovec __user *iov;
|
|
|
+ if (nr_segs > UIO_MAXIOV)
|
|
|
+ return -EINVAL;
|
|
|
+ iov = compat_alloc_user_space(nr_segs * sizeof(struct iovec));
|
|
|
+ for (i = 0; i < nr_segs; i++) {
|
|
|
+ struct compat_iovec v;
|
|
|
+ if (get_user(v.iov_base, &iov32[i].iov_base) ||
|
|
|
+ get_user(v.iov_len, &iov32[i].iov_len) ||
|
|
|
+ put_user(compat_ptr(v.iov_base), &iov[i].iov_base) ||
|
|
|
+ put_user(v.iov_len, &iov[i].iov_len))
|
|
|
+ return -EFAULT;
|
|
|
+ }
|
|
|
+ return sys_vmsplice(fd, iov, nr_segs, flags);
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in,
|
|
|
int, fd_out, loff_t __user *, off_out,
|
|
|
size_t, len, unsigned int, flags)
|