aboutsummaryrefslogtreecommitdiffstats
path: root/fs/splice.c
diff options
context:
space:
mode:
authorJens Axboe <axboe@suse.de>2006-04-02 17:05:09 -0400
committerJens Axboe <axboe@suse.de>2006-04-02 17:05:09 -0400
commit83f9135bddffded9f1716519b6c147bcf046c87e (patch)
tree24ed3b7e21cda62ff2a1947d04a1333066a5bc65 /fs/splice.c
parent4f6f0bd2ffa4e31c3524f5e65c84a29b6ab73307 (diff)
[PATCH] splice: add comments documenting more of the code
Hopefully this will make Andrew a little more happy. Signed-off-by: Jens Axboe <axboe@suse.de>
Diffstat (limited to 'fs/splice.c')
-rw-r--r--fs/splice.c70
1 files changed, 66 insertions, 4 deletions
diff --git a/fs/splice.c b/fs/splice.c
index 07f4d863c2d4..34591924c783 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -37,6 +37,12 @@ struct splice_desc {
37 loff_t pos; /* file position */ 37 loff_t pos; /* file position */
38}; 38};
39 39
40/*
41 * Attempt to steal a page from a pipe buffer. This should perhaps go into
42 * a vm helper function, it's already simplified quite a bit by the
43 * addition of remove_mapping(). If success is returned, the caller may
44 * attempt to reuse this page for another destination.
45 */
40static int page_cache_pipe_buf_steal(struct pipe_inode_info *info, 46static int page_cache_pipe_buf_steal(struct pipe_inode_info *info,
41 struct pipe_buffer *buf) 47 struct pipe_buffer *buf)
42{ 48{
@@ -108,6 +114,10 @@ static struct pipe_buf_operations page_cache_pipe_buf_ops = {
108 .steal = page_cache_pipe_buf_steal, 114 .steal = page_cache_pipe_buf_steal,
109}; 115};
110 116
117/*
118 * Pipe output worker. This sets up our pipe format with the page cache
119 * pipe buffer operations. Otherwise very similar to the regular pipe_writev().
120 */
111static ssize_t move_to_pipe(struct inode *inode, struct page **pages, 121static ssize_t move_to_pipe(struct inode *inode, struct page **pages,
112 int nr_pages, unsigned long offset, 122 int nr_pages, unsigned long offset,
113 unsigned long len, unsigned int flags) 123 unsigned long len, unsigned int flags)
@@ -292,6 +302,16 @@ splice_them:
292 return move_to_pipe(pipe, pages, i, offset, len, flags); 302 return move_to_pipe(pipe, pages, i, offset, len, flags);
293} 303}
294 304
305/**
306 * generic_file_splice_read - splice data from file to a pipe
307 * @in: file to splice from
308 * @pipe: pipe to splice to
309 * @len: number of bytes to splice
310 * @flags: splice modifier flags
311 *
312 * Will read pages from given file and fill them into a pipe.
313 *
314 */
295ssize_t generic_file_splice_read(struct file *in, struct inode *pipe, 315ssize_t generic_file_splice_read(struct file *in, struct inode *pipe,
296 size_t len, unsigned int flags) 316 size_t len, unsigned int flags)
297{ 317{
@@ -370,10 +390,12 @@ static int pipe_to_sendpage(struct pipe_inode_info *info,
370 * - Destination page does not exist, we can add the pipe page to 390 * - Destination page does not exist, we can add the pipe page to
371 * the page cache and avoid the copy. 391 * the page cache and avoid the copy.
372 * 392 *
373 * For now we just do the slower thing and always copy pages over, it's 393 * If asked to move pages to the output file (SPLICE_F_MOVE is set in
374 * easier than migrating pages from the pipe to the target file. For the 394 * sd->flags), we attempt to migrate pages from the pipe to the output
375 * case of doing file | file splicing, the migrate approach had some LRU 395 * file address space page cache. This is possible if no one else has
376 * nastiness... 396 * the pipe page referenced outside of the pipe and page cache. If
397 * SPLICE_F_MOVE isn't set, or we cannot move the page, we simply create
398 * a new page in the output file page cache and fill/dirty that.
377 */ 399 */
378static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf, 400static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf,
379 struct splice_desc *sd) 401 struct splice_desc *sd)
@@ -401,6 +423,10 @@ static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf,
401 * reuse buf page, if SPLICE_F_MOVE is set 423 * reuse buf page, if SPLICE_F_MOVE is set
402 */ 424 */
403 if (sd->flags & SPLICE_F_MOVE) { 425 if (sd->flags & SPLICE_F_MOVE) {
426 /*
427 * If steal succeeds, buf->page is now pruned from the vm
428 * side (LRU and page cache) and we can reuse it.
429 */
404 if (buf->ops->steal(info, buf)) 430 if (buf->ops->steal(info, buf))
405 goto find_page; 431 goto find_page;
406 432
@@ -484,6 +510,11 @@ out:
484typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *, 510typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,
485 struct splice_desc *); 511 struct splice_desc *);
486 512
513/*
514 * Pipe input worker. Most of this logic works like a regular pipe, the
515 * key here is the 'actor' worker passed in that actually moves the data
516 * to the wanted destination. See pipe_to_file/pipe_to_sendpage above.
517 */
487static ssize_t move_from_pipe(struct inode *inode, struct file *out, 518static ssize_t move_from_pipe(struct inode *inode, struct file *out,
488 size_t len, unsigned int flags, 519 size_t len, unsigned int flags,
489 splice_actor *actor) 520 splice_actor *actor)
@@ -585,6 +616,17 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out,
585 616
586} 617}
587 618
619/**
620 * generic_file_splice_write - splice data from a pipe to a file
621 * @inode: pipe inode
622 * @out: file to write to
623 * @len: number of bytes to splice
624 * @flags: splice modifier flags
625 *
626 * Will either move or copy pages (determined by @flags options) from
627 * the given pipe inode to the given file.
628 *
629 */
588ssize_t generic_file_splice_write(struct inode *inode, struct file *out, 630ssize_t generic_file_splice_write(struct inode *inode, struct file *out,
589 size_t len, unsigned int flags) 631 size_t len, unsigned int flags)
590{ 632{
@@ -611,6 +653,17 @@ ssize_t generic_file_splice_write(struct inode *inode, struct file *out,
611 return ret; 653 return ret;
612} 654}
613 655
656/**
657 * generic_splice_sendpage - splice data from a pipe to a socket
658 * @inode: pipe inode
659 * @out: socket to write to
660 * @len: number of bytes to splice
661 * @flags: splice modifier flags
662 *
663 * Will send @len bytes from the pipe to a network socket. No data copying
664 * is involved.
665 *
666 */
614ssize_t generic_splice_sendpage(struct inode *inode, struct file *out, 667ssize_t generic_splice_sendpage(struct inode *inode, struct file *out,
615 size_t len, unsigned int flags) 668 size_t len, unsigned int flags)
616{ 669{
@@ -620,6 +673,9 @@ ssize_t generic_splice_sendpage(struct inode *inode, struct file *out,
620EXPORT_SYMBOL(generic_file_splice_write); 673EXPORT_SYMBOL(generic_file_splice_write);
621EXPORT_SYMBOL(generic_file_splice_read); 674EXPORT_SYMBOL(generic_file_splice_read);
622 675
676/*
677 * Attempt to initiate a splice from pipe to file.
678 */
623static long do_splice_from(struct inode *pipe, struct file *out, size_t len, 679static long do_splice_from(struct inode *pipe, struct file *out, size_t len,
624 unsigned int flags) 680 unsigned int flags)
625{ 681{
@@ -640,6 +696,9 @@ static long do_splice_from(struct inode *pipe, struct file *out, size_t len,
640 return out->f_op->splice_write(pipe, out, len, flags); 696 return out->f_op->splice_write(pipe, out, len, flags);
641} 697}
642 698
699/*
700 * Attempt to initiate a splice from a file to a pipe.
701 */
643static long do_splice_to(struct file *in, struct inode *pipe, size_t len, 702static long do_splice_to(struct file *in, struct inode *pipe, size_t len,
644 unsigned int flags) 703 unsigned int flags)
645{ 704{
@@ -668,6 +727,9 @@ static long do_splice_to(struct file *in, struct inode *pipe, size_t len,
668 return in->f_op->splice_read(in, pipe, len, flags); 727 return in->f_op->splice_read(in, pipe, len, flags);
669} 728}
670 729
730/*
731 * Determine where to splice to/from.
732 */
671static long do_splice(struct file *in, struct file *out, size_t len, 733static long do_splice(struct file *in, struct file *out, size_t len,
672 unsigned int flags) 734 unsigned int flags)
673{ 735{