aboutsummaryrefslogtreecommitdiffstats
path: root/fs/splice.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/splice.c')
-rw-r--r--fs/splice.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/fs/splice.c b/fs/splice.c
index 29e394e49ddd..6b485b8753bd 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -31,6 +31,7 @@
31#include <linux/security.h> 31#include <linux/security.h>
32#include <linux/gfp.h> 32#include <linux/gfp.h>
33#include <linux/socket.h> 33#include <linux/socket.h>
34#include <linux/compat.h>
34#include "internal.h" 35#include "internal.h"
35 36
36/* 37/*
@@ -1690,6 +1691,27 @@ SYSCALL_DEFINE4(vmsplice, int, fd, const struct iovec __user *, iov,
1690 return error; 1691 return error;
1691} 1692}
1692 1693
1694#ifdef CONFIG_COMPAT
1695COMPAT_SYSCALL_DEFINE4(vmsplice, int, fd, const struct compat_iovec __user *, iov32,
1696 unsigned int, nr_segs, unsigned int, flags)
1697{
1698 unsigned i;
1699 struct iovec __user *iov;
1700 if (nr_segs > UIO_MAXIOV)
1701 return -EINVAL;
1702 iov = compat_alloc_user_space(nr_segs * sizeof(struct iovec));
1703 for (i = 0; i < nr_segs; i++) {
1704 struct compat_iovec v;
1705 if (get_user(v.iov_base, &iov32[i].iov_base) ||
1706 get_user(v.iov_len, &iov32[i].iov_len) ||
1707 put_user(compat_ptr(v.iov_base), &iov[i].iov_base) ||
1708 put_user(v.iov_len, &iov[i].iov_len))
1709 return -EFAULT;
1710 }
1711 return sys_vmsplice(fd, iov, nr_segs, flags);
1712}
1713#endif
1714
1693SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in, 1715SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in,
1694 int, fd_out, loff_t __user *, off_out, 1716 int, fd_out, loff_t __user *, off_out,
1695 size_t, len, unsigned int, flags) 1717 size_t, len, unsigned int, flags)