···37 loff_t pos; /* file position */38};3900000040static int page_cache_pipe_buf_steal(struct pipe_inode_info *info,41 struct pipe_buffer *buf)42{···114 .steal = page_cache_pipe_buf_steal,115};1160000117static ssize_t move_to_pipe(struct inode *inode, struct page **pages,118 int nr_pages, unsigned long offset,119 unsigned long len, unsigned int flags)···302 return move_to_pipe(pipe, pages, i, offset, len, flags);303}3040000000000305ssize_t generic_file_splice_read(struct file *in, struct inode *pipe,306 size_t len, unsigned int flags)307{···390 * - Destination page does not exist, we can add the pipe page to391 * the page cache and avoid the copy.392 *393- * For now we just do the slower thing and always copy pages over, it's394- * easier than migrating pages from the pipe to the target file. For the395- * case of doing file | file splicing, the migrate approach had some LRU396- * nastiness...00397 */398static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf,399 struct splice_desc *sd)···423 * reuse buf page, if SPLICE_F_MOVE is set424 */425 if (sd->flags & SPLICE_F_MOVE) {0000426 if (buf->ops->steal(info, buf))427 goto find_page;428···510typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,511 struct splice_desc *);51200000513static ssize_t move_from_pipe(struct inode *inode, struct file *out,514 size_t len, unsigned int flags,515 splice_actor *actor)···616617}61800000000000619ssize_t generic_file_splice_write(struct inode *inode, struct file *out,620 size_t len, unsigned int flags)621{···653 return ret;654}65500000000000656ssize_t generic_splice_sendpage(struct inode *inode, struct file *out,657 size_t len, unsigned int flags)658{···673EXPORT_SYMBOL(generic_file_splice_write);674EXPORT_SYMBOL(generic_file_splice_read);675000676static long do_splice_from(struct inode *pipe, struct file *out, size_t len,677 unsigned int flags)678{···696 return out->f_op->splice_write(pipe, out, len, flags);697}698000699static long do_splice_to(struct file *in, struct inode *pipe, size_t len,700 unsigned int flags)701{···727 return in->f_op->splice_read(in, pipe, len, flags);728}729000730static long do_splice(struct file *in, struct file *out, size_t len,731 unsigned int flags)732{
···37 loff_t pos; /* file position */38};3940+/*41+ * Attempt to steal a page from a pipe buffer. This should perhaps go into42+ * a vm helper function, it's already simplified quite a bit by the43+ * addition of remove_mapping(). If success is returned, the caller may44+ * attempt to reuse this page for another destination.45+ */46static int page_cache_pipe_buf_steal(struct pipe_inode_info *info,47 struct pipe_buffer *buf)48{···108 .steal = page_cache_pipe_buf_steal,109};110111+/*112+ * Pipe output worker. This sets up our pipe format with the page cache113+ * pipe buffer operations. Otherwise very similar to the regular pipe_writev().114+ */115static ssize_t move_to_pipe(struct inode *inode, struct page **pages,116 int nr_pages, unsigned long offset,117 unsigned long len, unsigned int flags)···292 return move_to_pipe(pipe, pages, i, offset, len, flags);293}294295+/**296+ * generic_file_splice_read - splice data from file to a pipe297+ * @in: file to splice from298+ * @pipe: pipe to splice to299+ * @len: number of bytes to splice300+ * @flags: splice modifier flags301+ *302+ * Will read pages from given file and fill them into a pipe.303+ *304+ */305ssize_t generic_file_splice_read(struct file *in, struct inode *pipe,306 size_t len, unsigned int flags)307{···370 * - Destination page does not exist, we can add the pipe page to371 * the page cache and avoid the copy.372 *373+ * If asked to move pages to the output file (SPLICE_F_MOVE is set in374+ * sd->flags), we attempt to migrate pages from the pipe to the output375+ * file address space page cache. This is possible if no one else has376+ * the pipe page referenced outside of the pipe and page cache. If377+ * SPLICE_F_MOVE isn't set, or we cannot move the page, we simply create378+ * a new page in the output file page cache and fill/dirty that.379 */380static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf,381 struct splice_desc *sd)···401 * reuse buf page, if SPLICE_F_MOVE is set402 */403 if (sd->flags & SPLICE_F_MOVE) {404+ /*405+ * If steal succeeds, buf->page is now pruned from the vm406+ * side (LRU and page cache) and we can reuse it.407+ */408 if (buf->ops->steal(info, buf))409 goto find_page;410···484typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,485 struct splice_desc *);486487+/*488+ * Pipe input worker. Most of this logic works like a regular pipe, the489+ * key here is the 'actor' worker passed in that actually moves the data490+ * to the wanted destination. See pipe_to_file/pipe_to_sendpage above.491+ */492static ssize_t move_from_pipe(struct inode *inode, struct file *out,493 size_t len, unsigned int flags,494 splice_actor *actor)···585586}587588+/**589+ * generic_file_splice_write - splice data from a pipe to a file590+ * @inode: pipe inode591+ * @out: file to write to592+ * @len: number of bytes to splice593+ * @flags: splice modifier flags594+ *595+ * Will either move or copy pages (determined by @flags options) from596+ * the given pipe inode to the given file.597+ *598+ */599ssize_t generic_file_splice_write(struct inode *inode, struct file *out,600 size_t len, unsigned int flags)601{···611 return ret;612}613614+/**615+ * generic_splice_sendpage - splice data from a pipe to a socket616+ * @inode: pipe inode617+ * @out: socket to write to618+ * @len: number of bytes to splice619+ * @flags: splice modifier flags620+ *621+ * Will send @len bytes from the pipe to a network socket. No data copying622+ * is involved.623+ *624+ */625ssize_t generic_splice_sendpage(struct inode *inode, struct file *out,626 size_t len, unsigned int flags)627{···620EXPORT_SYMBOL(generic_file_splice_write);621EXPORT_SYMBOL(generic_file_splice_read);622623+/*624+ * Attempt to initiate a splice from pipe to file.625+ */626static long do_splice_from(struct inode *pipe, struct file *out, size_t len,627 unsigned int flags)628{···640 return out->f_op->splice_write(pipe, out, len, flags);641}642643+/*644+ * Attempt to initiate a splice from a file to a pipe.645+ */646static long do_splice_to(struct file *in, struct inode *pipe, size_t len,647 unsigned int flags)648{···668 return in->f_op->splice_read(in, pipe, len, flags);669}670671+/*672+ * Determine where to splice to/from.673+ */674static long do_splice(struct file *in, struct file *out, size_t len,675 unsigned int flags)676{