Merge branch 'work.splice' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[sfrench/cifs-2.6.git] / fs / splice.c
index 006ba50f4ece671f48367b644641ab58b04b65d8..540c4a44756c20cdd0e7e2f3eb3db98712858210 100644 (file)
@@ -247,11 +247,6 @@ ssize_t add_to_pipe(struct pipe_inode_info *pipe, struct pipe_buffer *buf)
 }
 EXPORT_SYMBOL(add_to_pipe);
 
-void spd_release_page(struct splice_pipe_desc *spd, unsigned int i)
-{
-       put_page(spd->pages[i]);
-}
-
 /*
  * Check if we need to grow the arrays holding pages and partial page
  * descriptions.
@@ -393,7 +388,7 @@ static ssize_t default_file_splice_read(struct file *in, loff_t *ppos,
        struct iov_iter to;
        struct page **pages;
        unsigned int nr_pages;
-       size_t offset, dummy, copied = 0;
+       size_t offset, base, copied = 0;
        ssize_t res;
        int i;
 
@@ -408,12 +403,11 @@ static ssize_t default_file_splice_read(struct file *in, loff_t *ppos,
 
        iov_iter_pipe(&to, ITER_PIPE | READ, pipe, len + offset);
 
-       res = iov_iter_get_pages_alloc(&to, &pages, len + offset, &dummy);
+       res = iov_iter_get_pages_alloc(&to, &pages, len + offset, &base);
        if (res <= 0)
                return -ENOMEM;
 
-       BUG_ON(dummy);
-       nr_pages = DIV_ROUND_UP(res, PAGE_SIZE);
+       nr_pages = DIV_ROUND_UP(res + base, PAGE_SIZE);
 
        vec = __vec;
        if (nr_pages > PIPE_DEF_BUFFERS) {
@@ -1359,6 +1353,8 @@ SYSCALL_DEFINE4(vmsplice, int, fd, const struct iovec __user *, iov,
        struct fd f;
        long error;
 
+       if (unlikely(flags & ~SPLICE_F_ALL))
+               return -EINVAL;
        if (unlikely(nr_segs > UIO_MAXIOV))
                return -EINVAL;
        else if (unlikely(!nr_segs))
@@ -1409,6 +1405,9 @@ SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in,
        if (unlikely(!len))
                return 0;
 
+       if (unlikely(flags & ~SPLICE_F_ALL))
+               return -EINVAL;
+
        error = -EBADF;
        in = fdget(fd_in);
        if (in.file) {
@@ -1737,6 +1736,9 @@ SYSCALL_DEFINE4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags)
        struct fd in;
        int error;
 
+       if (unlikely(flags & ~SPLICE_F_ALL))
+               return -EINVAL;
+
        if (unlikely(!len))
                return 0;