diff options
| author | Jens Axboe <axboe@suse.de> | 2006-04-26 08:39:29 -0400 |
|---|---|---|
| committer | Jens Axboe <axboe@suse.de> | 2006-04-26 08:39:29 -0400 |
| commit | 00522fb41a2a9bf0f98a007c0e2b516a3873148c (patch) | |
| tree | 18bcbfb598f0ad0a4745aaee25dab6dccc6449a1 | |
| parent | 912d35f86781e64d73be1ef358f703c08905ac37 (diff) | |
[PATCH] splice: rearrange moving to/from pipe helpers
We need these for people writing their own ->splice_read/write hooks.
Signed-off-by: Jens Axboe <axboe@suse.de>
| -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 0b2c1f060c..447ebc0a37 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 ef7f33c0be..0008d4bd40 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 |
