Merge branch 'work.splice' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 2 May 2017 18:38:06 +0000 (11:38 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 2 May 2017 18:38:06 +0000 (11:38 -0700)
Pull splice updates from Al Viro:
 "These actually missed the last cycle; the branch itself is from last
  December"

* 'work.splice' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  make nr_pages calculation in default_file_splice_read() a bit less ugly
  splice/tee/vmsplice: validate flags
  splice_pipe_desc: kill ->flags
  remove spd_release_page()

fs/splice.c
include/linux/splice.h
kernel/relay.c
kernel/trace/trace.c
net/core/skbuff.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;
 
index 00a21166e268b50f812807bc7e899360cb65febc..db42746bdfea54858ba2fae9fdaf5e4141b478a9 100644 (file)
@@ -20,6 +20,8 @@
 #define SPLICE_F_MORE  (0x04)  /* expect more data */
 #define SPLICE_F_GIFT  (0x08)  /* pages passed in are a gift */
 
+#define SPLICE_F_ALL (SPLICE_F_MOVE|SPLICE_F_NONBLOCK|SPLICE_F_MORE|SPLICE_F_GIFT)
+
 /*
  * Passed to the actors
  */
@@ -55,7 +57,6 @@ struct splice_pipe_desc {
        struct partial_page *partial;   /* pages[] may not be contig */
        int nr_pages;                   /* number of populated pages in map */
        unsigned int nr_pages_max;      /* pages[] & partial[] arrays size */
-       unsigned int flags;             /* splice flags */
        const struct pipe_buf_operations *ops;/* ops associated with output pipe */
        void (*spd_release)(struct splice_pipe_desc *, unsigned int);
 };
@@ -82,7 +83,6 @@ extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *,
  */
 extern int splice_grow_spd(const struct pipe_inode_info *, struct splice_pipe_desc *);
 extern void splice_shrink_spd(struct splice_pipe_desc *);
-extern void spd_release_page(struct splice_pipe_desc *, unsigned int);
 
 extern const struct pipe_buf_operations page_cache_pipe_buf_ops;
 extern const struct pipe_buf_operations default_pipe_buf_ops;
index 0e413d9eec8af484517300e1c142325356865771..39a9dfc69486b57a85d115dcefee75d35907a74d 100644 (file)
@@ -1212,7 +1212,6 @@ static ssize_t subbuf_splice_actor(struct file *in,
                .nr_pages = 0,
                .nr_pages_max = PIPE_DEF_BUFFERS,
                .partial = partial,
-               .flags = flags,
                .ops = &relay_pipe_buf_ops,
                .spd_release = relay_page_release,
        };
index b253d59b9c518a4c71ad03d2e4940e782dd4e8a4..0029fe62b2450361923ebb93346206cded759a09 100644 (file)
@@ -5530,7 +5530,6 @@ static ssize_t tracing_splice_read_pipe(struct file *filp,
                .partial        = partial_def,
                .nr_pages       = 0, /* This gets updated below. */
                .nr_pages_max   = PIPE_DEF_BUFFERS,
-               .flags          = flags,
                .ops            = &tracing_pipe_buf_ops,
                .spd_release    = tracing_spd_release_pipe,
        };
@@ -6428,7 +6427,6 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
                .pages          = pages_def,
                .partial        = partial_def,
                .nr_pages_max   = PIPE_DEF_BUFFERS,
-               .flags          = flags,
                .ops            = &buffer_pipe_buf_ops,
                .spd_release    = buffer_spd_release,
        };
index f1d04592ace02f32efa6e05df89c9a5e0023157f..b782b4593f8cbc005ebb8d8befc148f96cc325f5 100644 (file)
@@ -1982,7 +1982,6 @@ int skb_splice_bits(struct sk_buff *skb, struct sock *sk, unsigned int offset,
                .pages = pages,
                .partial = partial,
                .nr_pages_max = MAX_SKB_FRAGS,
-               .flags = flags,
                .ops = &nosteal_pipe_buf_ops,
                .spd_release = sock_spd_release,
        };