diff options
-rw-r--r-- | fs/splice.c | 35 | ||||
-rw-r--r-- | include/linux/pipe_fs_i.h | 17 |
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 | */ | ||
35 | struct 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 | |||
42 | struct partial_page { | 32 | struct 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 | */ |
50 | struct splice_pipe_desc { | 40 | struct 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 | */ |
195 | static ssize_t move_to_pipe(struct pipe_inode_info *pipe, | 185 | static 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 | ||
669 | typedef 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 | */ |
677 | static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out, | 664 | ssize_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); | |||
837 | ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out, | 824 | ssize_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 | ||
843 | EXPORT_SYMBOL(generic_splice_sendpage); | 830 | EXPORT_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 | ||
1216 | asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov, | 1203 | asmlinkage 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 | */ | ||
67 | struct 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 | |||
74 | typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *, | ||
75 | struct splice_desc *); | ||
76 | |||
77 | extern 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 |