aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/splice.c35
-rw-r--r--include/linux/pipe_fs_i.h17
2 files changed, 28 insertions, 24 deletions
diff --git a/fs/splice.c b/fs/splice.c
index 0b2c1f060cae..447ebc0a37f3 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -29,23 +29,13 @@
29#include <linux/syscalls.h> 29#include <linux/syscalls.h>
30#include <linux/uio.h> 30#include <linux/uio.h>
31 31
32/*
33 * Passed to the actors
34 */
35struct splice_desc {
36 unsigned int len, total_len; /* current and remaining length */
37 unsigned int flags; /* splice flags */
38 struct file *file; /* file to read/write */
39 loff_t pos; /* file position */
40};
41
42struct partial_page { 32struct partial_page {
43 unsigned int offset; 33 unsigned int offset;
44 unsigned int len; 34 unsigned int len;
45}; 35};
46 36
47/* 37/*
48 * Passed to move_to_pipe 38 * Passed to splice_to_pipe
49 */ 39 */
50struct splice_pipe_desc { 40struct splice_pipe_desc {
51 struct page **pages; /* page map */ 41 struct page **pages; /* page map */
@@ -192,8 +182,8 @@ static struct pipe_buf_operations user_page_pipe_buf_ops = {
192 * Pipe output worker. This sets up our pipe format with the page cache 182 * Pipe output worker. This sets up our pipe format with the page cache
193 * pipe buffer operations. Otherwise very similar to the regular pipe_writev(). 183 * pipe buffer operations. Otherwise very similar to the regular pipe_writev().
194 */ 184 */
195static ssize_t move_to_pipe(struct pipe_inode_info *pipe, 185static ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
196 struct splice_pipe_desc *spd) 186 struct splice_pipe_desc *spd)
197{ 187{
198 int ret, do_wakeup, page_nr; 188 int ret, do_wakeup, page_nr;
199 189
@@ -432,7 +422,7 @@ fill_it:
432 } 422 }
433 423
434 if (spd.nr_pages) 424 if (spd.nr_pages)
435 return move_to_pipe(pipe, &spd); 425 return splice_to_pipe(pipe, &spd);
436 426
437 return error; 427 return error;
438} 428}
@@ -666,17 +656,14 @@ out_nomem:
666 return ret; 656 return ret;
667} 657}
668 658
669typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,
670 struct splice_desc *);
671
672/* 659/*
673 * Pipe input worker. Most of this logic works like a regular pipe, the 660 * Pipe input worker. Most of this logic works like a regular pipe, the
674 * key here is the 'actor' worker passed in that actually moves the data 661 * key here is the 'actor' worker passed in that actually moves the data
675 * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. 662 * to the wanted destination. See pipe_to_file/pipe_to_sendpage above.
676 */ 663 */
677static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out, 664ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
678 loff_t *ppos, size_t len, unsigned int flags, 665 loff_t *ppos, size_t len, unsigned int flags,
679 splice_actor *actor) 666 splice_actor *actor)
680{ 667{
681 int ret, do_wakeup, err; 668 int ret, do_wakeup, err;
682 struct splice_desc sd; 669 struct splice_desc sd;
@@ -795,7 +782,7 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
795 struct address_space *mapping = out->f_mapping; 782 struct address_space *mapping = out->f_mapping;
796 ssize_t ret; 783 ssize_t ret;
797 784
798 ret = move_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); 785 ret = splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file);
799 if (ret > 0) { 786 if (ret > 0) {
800 struct inode *inode = mapping->host; 787 struct inode *inode = mapping->host;
801 788
@@ -837,7 +824,7 @@ EXPORT_SYMBOL(generic_file_splice_write);
837ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out, 824ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out,
838 loff_t *ppos, size_t len, unsigned int flags) 825 loff_t *ppos, size_t len, unsigned int flags)
839{ 826{
840 return move_from_pipe(pipe, out, ppos, len, flags, pipe_to_sendpage); 827 return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_sendpage);
841} 828}
842 829
843EXPORT_SYMBOL(generic_splice_sendpage); 830EXPORT_SYMBOL(generic_splice_sendpage);
@@ -924,7 +911,7 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
924 911
925 /* 912 /*
926 * We don't have an immediate reader, but we'll read the stuff 913 * We don't have an immediate reader, but we'll read the stuff
927 * out of the pipe right after the move_to_pipe(). So set 914 * out of the pipe right after the splice_to_pipe(). So set
928 * PIPE_READERS appropriately. 915 * PIPE_READERS appropriately.
929 */ 916 */
930 pipe->readers = 1; 917 pipe->readers = 1;
@@ -1210,7 +1197,7 @@ static long do_vmsplice(struct file *file, const struct iovec __user *iov,
1210 if (spd.nr_pages <= 0) 1197 if (spd.nr_pages <= 0)
1211 return spd.nr_pages; 1198 return spd.nr_pages;
1212 1199
1213 return move_to_pipe(pipe, &spd); 1200 return splice_to_pipe(pipe, &spd);
1214} 1201}
1215 1202
1216asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov, 1203asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov,
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
index ef7f33c0be19..0008d4bd4059 100644
--- a/include/linux/pipe_fs_i.h
+++ b/include/linux/pipe_fs_i.h
@@ -61,4 +61,21 @@ void __free_pipe_info(struct pipe_inode_info *);
61 /* from/to, of course */ 61 /* from/to, of course */
62#define SPLICE_F_MORE (0x04) /* expect more data */ 62#define SPLICE_F_MORE (0x04) /* expect more data */
63 63
64/*
65 * Passed to the actors
66 */
67struct splice_desc {
68 unsigned int len, total_len; /* current and remaining length */
69 unsigned int flags; /* splice flags */
70 struct file *file; /* file to read/write */
71 loff_t pos; /* file position */
72};
73
74typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,
75 struct splice_desc *);
76
77extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *,
78 loff_t *, size_t, unsigned int,
79 splice_actor *);
80
64#endif 81#endif