Commit da7b66ff authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'work.splice' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

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()
parents 5b13475a 13c0f52b
...@@ -247,11 +247,6 @@ ssize_t add_to_pipe(struct pipe_inode_info *pipe, struct pipe_buffer *buf) ...@@ -247,11 +247,6 @@ ssize_t add_to_pipe(struct pipe_inode_info *pipe, struct pipe_buffer *buf)
} }
EXPORT_SYMBOL(add_to_pipe); 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 * Check if we need to grow the arrays holding pages and partial page
* descriptions. * descriptions.
...@@ -393,7 +388,7 @@ static ssize_t default_file_splice_read(struct file *in, loff_t *ppos, ...@@ -393,7 +388,7 @@ static ssize_t default_file_splice_read(struct file *in, loff_t *ppos,
struct iov_iter to; struct iov_iter to;
struct page **pages; struct page **pages;
unsigned int nr_pages; unsigned int nr_pages;
size_t offset, dummy, copied = 0; size_t offset, base, copied = 0;
ssize_t res; ssize_t res;
int i; int i;
...@@ -408,12 +403,11 @@ static ssize_t default_file_splice_read(struct file *in, loff_t *ppos, ...@@ -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); 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) if (res <= 0)
return -ENOMEM; return -ENOMEM;
BUG_ON(dummy); nr_pages = DIV_ROUND_UP(res + base, PAGE_SIZE);
nr_pages = DIV_ROUND_UP(res, PAGE_SIZE);
vec = __vec; vec = __vec;
if (nr_pages > PIPE_DEF_BUFFERS) { if (nr_pages > PIPE_DEF_BUFFERS) {
...@@ -1359,6 +1353,8 @@ SYSCALL_DEFINE4(vmsplice, int, fd, const struct iovec __user *, iov, ...@@ -1359,6 +1353,8 @@ SYSCALL_DEFINE4(vmsplice, int, fd, const struct iovec __user *, iov,
struct fd f; struct fd f;
long error; long error;
if (unlikely(flags & ~SPLICE_F_ALL))
return -EINVAL;
if (unlikely(nr_segs > UIO_MAXIOV)) if (unlikely(nr_segs > UIO_MAXIOV))
return -EINVAL; return -EINVAL;
else if (unlikely(!nr_segs)) else if (unlikely(!nr_segs))
...@@ -1409,6 +1405,9 @@ SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in, ...@@ -1409,6 +1405,9 @@ SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in,
if (unlikely(!len)) if (unlikely(!len))
return 0; return 0;
if (unlikely(flags & ~SPLICE_F_ALL))
return -EINVAL;
error = -EBADF; error = -EBADF;
in = fdget(fd_in); in = fdget(fd_in);
if (in.file) { if (in.file) {
...@@ -1737,6 +1736,9 @@ SYSCALL_DEFINE4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags) ...@@ -1737,6 +1736,9 @@ SYSCALL_DEFINE4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags)
struct fd in; struct fd in;
int error; int error;
if (unlikely(flags & ~SPLICE_F_ALL))
return -EINVAL;
if (unlikely(!len)) if (unlikely(!len))
return 0; return 0;
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#define SPLICE_F_MORE (0x04) /* expect more data */ #define SPLICE_F_MORE (0x04) /* expect more data */
#define SPLICE_F_GIFT (0x08) /* pages passed in are a gift */ #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 * Passed to the actors
*/ */
...@@ -55,7 +57,6 @@ struct splice_pipe_desc { ...@@ -55,7 +57,6 @@ struct splice_pipe_desc {
struct partial_page *partial; /* pages[] may not be contig */ struct partial_page *partial; /* pages[] may not be contig */
int nr_pages; /* number of populated pages in map */ int nr_pages; /* number of populated pages in map */
unsigned int nr_pages_max; /* pages[] & partial[] arrays size */ 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 */ const struct pipe_buf_operations *ops;/* ops associated with output pipe */
void (*spd_release)(struct splice_pipe_desc *, unsigned int); 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 *, ...@@ -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 int splice_grow_spd(const struct pipe_inode_info *, struct splice_pipe_desc *);
extern void splice_shrink_spd(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 page_cache_pipe_buf_ops;
extern const struct pipe_buf_operations default_pipe_buf_ops; extern const struct pipe_buf_operations default_pipe_buf_ops;
......
...@@ -1212,7 +1212,6 @@ static ssize_t subbuf_splice_actor(struct file *in, ...@@ -1212,7 +1212,6 @@ static ssize_t subbuf_splice_actor(struct file *in,
.nr_pages = 0, .nr_pages = 0,
.nr_pages_max = PIPE_DEF_BUFFERS, .nr_pages_max = PIPE_DEF_BUFFERS,
.partial = partial, .partial = partial,
.flags = flags,
.ops = &relay_pipe_buf_ops, .ops = &relay_pipe_buf_ops,
.spd_release = relay_page_release, .spd_release = relay_page_release,
}; };
......
...@@ -5530,7 +5530,6 @@ static ssize_t tracing_splice_read_pipe(struct file *filp, ...@@ -5530,7 +5530,6 @@ static ssize_t tracing_splice_read_pipe(struct file *filp,
.partial = partial_def, .partial = partial_def,
.nr_pages = 0, /* This gets updated below. */ .nr_pages = 0, /* This gets updated below. */
.nr_pages_max = PIPE_DEF_BUFFERS, .nr_pages_max = PIPE_DEF_BUFFERS,
.flags = flags,
.ops = &tracing_pipe_buf_ops, .ops = &tracing_pipe_buf_ops,
.spd_release = tracing_spd_release_pipe, .spd_release = tracing_spd_release_pipe,
}; };
...@@ -6428,7 +6427,6 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, ...@@ -6428,7 +6427,6 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
.pages = pages_def, .pages = pages_def,
.partial = partial_def, .partial = partial_def,
.nr_pages_max = PIPE_DEF_BUFFERS, .nr_pages_max = PIPE_DEF_BUFFERS,
.flags = flags,
.ops = &buffer_pipe_buf_ops, .ops = &buffer_pipe_buf_ops,
.spd_release = buffer_spd_release, .spd_release = buffer_spd_release,
}; };
......
...@@ -1982,7 +1982,6 @@ int skb_splice_bits(struct sk_buff *skb, struct sock *sk, unsigned int offset, ...@@ -1982,7 +1982,6 @@ int skb_splice_bits(struct sk_buff *skb, struct sock *sk, unsigned int offset,
.pages = pages, .pages = pages,
.partial = partial, .partial = partial,
.nr_pages_max = MAX_SKB_FRAGS, .nr_pages_max = MAX_SKB_FRAGS,
.flags = flags,
.ops = &nosteal_pipe_buf_ops, .ops = &nosteal_pipe_buf_ops,
.spd_release = sock_spd_release, .spd_release = sock_spd_release,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment