Loading fs/splice.c +11 −24 Original line number Diff line number Diff line Loading @@ -29,23 +29,13 @@ #include <linux/syscalls.h> #include <linux/uio.h> /* * Passed to the actors */ struct splice_desc { unsigned int len, total_len; /* current and remaining length */ unsigned int flags; /* splice flags */ struct file *file; /* file to read/write */ loff_t pos; /* file position */ }; struct partial_page { unsigned int offset; unsigned int len; }; /* * Passed to move_to_pipe * Passed to splice_to_pipe */ struct splice_pipe_desc { struct page **pages; /* page map */ Loading Loading @@ -192,7 +182,7 @@ static struct pipe_buf_operations user_page_pipe_buf_ops = { * Pipe output worker. This sets up our pipe format with the page cache * pipe buffer operations. Otherwise very similar to the regular pipe_writev(). */ static ssize_t move_to_pipe(struct pipe_inode_info *pipe, static ssize_t splice_to_pipe(struct pipe_inode_info *pipe, struct splice_pipe_desc *spd) { int ret, do_wakeup, page_nr; Loading Loading @@ -432,7 +422,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, } if (spd.nr_pages) return move_to_pipe(pipe, &spd); return splice_to_pipe(pipe, &spd); return error; } Loading Loading @@ -666,15 +656,12 @@ static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf, return ret; } typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *, struct splice_desc *); /* * Pipe input worker. Most of this logic works like a regular pipe, the * key here is the 'actor' worker passed in that actually moves the data * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. */ static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out, ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, loff_t *ppos, size_t len, unsigned int flags, splice_actor *actor) { Loading Loading @@ -795,7 +782,7 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, struct address_space *mapping = out->f_mapping; ssize_t ret; ret = move_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); ret = splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); if (ret > 0) { struct inode *inode = mapping->host; Loading Loading @@ -837,7 +824,7 @@ EXPORT_SYMBOL(generic_file_splice_write); ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out, loff_t *ppos, size_t len, unsigned int flags) { return move_from_pipe(pipe, out, ppos, len, flags, pipe_to_sendpage); return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_sendpage); } EXPORT_SYMBOL(generic_splice_sendpage); Loading Loading @@ -924,7 +911,7 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, /* * We don't have an immediate reader, but we'll read the stuff * out of the pipe right after the move_to_pipe(). So set * out of the pipe right after the splice_to_pipe(). So set * PIPE_READERS appropriately. */ pipe->readers = 1; Loading Loading @@ -1210,7 +1197,7 @@ static long do_vmsplice(struct file *file, const struct iovec __user *iov, if (spd.nr_pages <= 0) return spd.nr_pages; return move_to_pipe(pipe, &spd); return splice_to_pipe(pipe, &spd); } asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov, Loading include/linux/pipe_fs_i.h +17 −0 Original line number Diff line number Diff line Loading @@ -61,4 +61,21 @@ void __free_pipe_info(struct pipe_inode_info *); /* from/to, of course */ #define SPLICE_F_MORE (0x04) /* expect more data */ /* * Passed to the actors */ struct splice_desc { unsigned int len, total_len; /* current and remaining length */ unsigned int flags; /* splice flags */ struct file *file; /* file to read/write */ loff_t pos; /* file position */ }; typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *, struct splice_desc *); extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int, splice_actor *); #endif Loading
fs/splice.c +11 −24 Original line number Diff line number Diff line Loading @@ -29,23 +29,13 @@ #include <linux/syscalls.h> #include <linux/uio.h> /* * Passed to the actors */ struct splice_desc { unsigned int len, total_len; /* current and remaining length */ unsigned int flags; /* splice flags */ struct file *file; /* file to read/write */ loff_t pos; /* file position */ }; struct partial_page { unsigned int offset; unsigned int len; }; /* * Passed to move_to_pipe * Passed to splice_to_pipe */ struct splice_pipe_desc { struct page **pages; /* page map */ Loading Loading @@ -192,7 +182,7 @@ static struct pipe_buf_operations user_page_pipe_buf_ops = { * Pipe output worker. This sets up our pipe format with the page cache * pipe buffer operations. Otherwise very similar to the regular pipe_writev(). */ static ssize_t move_to_pipe(struct pipe_inode_info *pipe, static ssize_t splice_to_pipe(struct pipe_inode_info *pipe, struct splice_pipe_desc *spd) { int ret, do_wakeup, page_nr; Loading Loading @@ -432,7 +422,7 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, } if (spd.nr_pages) return move_to_pipe(pipe, &spd); return splice_to_pipe(pipe, &spd); return error; } Loading Loading @@ -666,15 +656,12 @@ static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf, return ret; } typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *, struct splice_desc *); /* * Pipe input worker. Most of this logic works like a regular pipe, the * key here is the 'actor' worker passed in that actually moves the data * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. */ static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out, ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, loff_t *ppos, size_t len, unsigned int flags, splice_actor *actor) { Loading Loading @@ -795,7 +782,7 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, struct address_space *mapping = out->f_mapping; ssize_t ret; ret = move_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); ret = splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); if (ret > 0) { struct inode *inode = mapping->host; Loading Loading @@ -837,7 +824,7 @@ EXPORT_SYMBOL(generic_file_splice_write); ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out, loff_t *ppos, size_t len, unsigned int flags) { return move_from_pipe(pipe, out, ppos, len, flags, pipe_to_sendpage); return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_sendpage); } EXPORT_SYMBOL(generic_splice_sendpage); Loading Loading @@ -924,7 +911,7 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, /* * We don't have an immediate reader, but we'll read the stuff * out of the pipe right after the move_to_pipe(). So set * out of the pipe right after the splice_to_pipe(). So set * PIPE_READERS appropriately. */ pipe->readers = 1; Loading Loading @@ -1210,7 +1197,7 @@ static long do_vmsplice(struct file *file, const struct iovec __user *iov, if (spd.nr_pages <= 0) return spd.nr_pages; return move_to_pipe(pipe, &spd); return splice_to_pipe(pipe, &spd); } asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov, Loading
include/linux/pipe_fs_i.h +17 −0 Original line number Diff line number Diff line Loading @@ -61,4 +61,21 @@ void __free_pipe_info(struct pipe_inode_info *); /* from/to, of course */ #define SPLICE_F_MORE (0x04) /* expect more data */ /* * Passed to the actors */ struct splice_desc { unsigned int len, total_len; /* current and remaining length */ unsigned int flags; /* splice flags */ struct file *file; /* file to read/write */ loff_t pos; /* file position */ }; typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *, struct splice_desc *); extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int, splice_actor *); #endif