Commit 932cc6d4 authored by Jens Axboe's avatar Jens Axboe

splice: completely document external interface with kerneldoc

Also add fs/splice.c as a kerneldoc target with a smaller blurb that
should be expanded to better explain the overview of splice.
Signed-off-by: default avatarJens Axboe <jens.axboe@oracle.com>
parent d6f51756
...@@ -643,4 +643,15 @@ X!Idrivers/video/console/fonts.c ...@@ -643,4 +643,15 @@ X!Idrivers/video/console/fonts.c
!Edrivers/spi/spi.c !Edrivers/spi/spi.c
</chapter> </chapter>
<chapter id="splice">
<title>splice API</title>
<para>)
splice is a method for moving blocks of data around inside the
kernel, without continually transferring it between the kernel
and user space.
</para>
!Iinclude/linux/splice.h
!Ffs/splice.c
</chapter>
</book> </book>
...@@ -153,9 +153,16 @@ static const struct pipe_buf_operations user_page_pipe_buf_ops = { ...@@ -153,9 +153,16 @@ static const struct pipe_buf_operations user_page_pipe_buf_ops = {
.get = generic_pipe_buf_get, .get = generic_pipe_buf_get,
}; };
/* /**
* Pipe output worker. This fills a pipe with the information contained * splice_to_pipe - fill passed data into a pipe
* from splice_pipe_desc(). * @pipe: pipe to fill
* @spd: data to fill
*
* Description:
* @spd contains a map of pages and len/offset tupples, a long with
* the struct pipe_buf_operations associated with these pages. This
* function will link that data to the pipe.
*
*/ */
ssize_t splice_to_pipe(struct pipe_inode_info *pipe, ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
struct splice_pipe_desc *spd) struct splice_pipe_desc *spd)
...@@ -280,11 +287,6 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, ...@@ -280,11 +287,6 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
*/ */
page_cache_readahead(mapping, &in->f_ra, in, index, nr_pages); page_cache_readahead(mapping, &in->f_ra, in, index, nr_pages);
/*
* Now fill in the holes:
*/
error = 0;
/* /*
* Lookup the (hopefully) full range of pages we need. * Lookup the (hopefully) full range of pages we need.
*/ */
...@@ -292,8 +294,9 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, ...@@ -292,8 +294,9 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
/* /*
* If find_get_pages_contig() returned fewer pages than we needed, * If find_get_pages_contig() returned fewer pages than we needed,
* allocate the rest. * allocate the rest and fill in the holes.
*/ */
error = 0;
index += spd.nr_pages; index += spd.nr_pages;
while (spd.nr_pages < nr_pages) { while (spd.nr_pages < nr_pages) {
/* /*
...@@ -455,11 +458,16 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, ...@@ -455,11 +458,16 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
/** /**
* generic_file_splice_read - splice data from file to a pipe * generic_file_splice_read - splice data from file to a pipe
* @in: file to splice from * @in: file to splice from
* @ppos: position in @in
* @pipe: pipe to splice to * @pipe: pipe to splice to
* @len: number of bytes to splice * @len: number of bytes to splice
* @flags: splice modifier flags * @flags: splice modifier flags
* *
* Will read pages from given file and fill them into a pipe. * Description:
* Will read pages from given file and fill them into a pipe. Can be
* used as long as the address_space operations for the source implements
* a readpage() hook.
*
*/ */
ssize_t generic_file_splice_read(struct file *in, loff_t *ppos, ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
struct pipe_inode_info *pipe, size_t len, struct pipe_inode_info *pipe, size_t len,
...@@ -648,10 +656,18 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, ...@@ -648,10 +656,18 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
return ret; return ret;
} }
/* /**
* Pipe input worker. Most of this logic works like a regular pipe, the * __splice_from_pipe - splice data from a pipe to given actor
* key here is the 'actor' worker passed in that actually moves the data * @pipe: pipe to splice from
* to the wanted destination. See pipe_to_file/pipe_to_sendpage above. * @sd: information to @actor
* @actor: handler that splices the data
*
* Description:
* This function does little more than loop over the pipe and call
* @actor to do the actual moving of a single struct pipe_buffer to
* the desired destination. See pipe_to_file, pipe_to_sendpage, or
* pipe_to_user.
*
*/ */
ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd, ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd,
splice_actor *actor) splice_actor *actor)
...@@ -744,6 +760,20 @@ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd, ...@@ -744,6 +760,20 @@ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd,
} }
EXPORT_SYMBOL(__splice_from_pipe); EXPORT_SYMBOL(__splice_from_pipe);
/**
* splice_from_pipe - splice data from a pipe to a file
* @pipe: pipe to splice from
* @out: file to splice to
* @ppos: position in @out
* @len: how many bytes to splice
* @flags: splice modifier flags
* @actor: handler that splices the data
*
* Description:
* See __splice_from_pipe. This function locks the input and output inodes,
* otherwise it's identical to __splice_from_pipe().
*
*/
ssize_t splice_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, loff_t *ppos, size_t len, unsigned int flags,
splice_actor *actor) splice_actor *actor)
...@@ -774,12 +804,14 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, ...@@ -774,12 +804,14 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
* generic_file_splice_write_nolock - generic_file_splice_write without mutexes * generic_file_splice_write_nolock - generic_file_splice_write without mutexes
* @pipe: pipe info * @pipe: pipe info
* @out: file to write to * @out: file to write to
* @ppos: position in @out
* @len: number of bytes to splice * @len: number of bytes to splice
* @flags: splice modifier flags * @flags: splice modifier flags
* *
* Will either move or copy pages (determined by @flags options) from * Description:
* the given pipe inode to the given file. The caller is responsible * Will either move or copy pages (determined by @flags options) from
* for acquiring i_mutex on both inodes. * the given pipe inode to the given file. The caller is responsible
* for acquiring i_mutex on both inodes.
* *
*/ */
ssize_t ssize_t
...@@ -831,11 +863,13 @@ EXPORT_SYMBOL(generic_file_splice_write_nolock); ...@@ -831,11 +863,13 @@ EXPORT_SYMBOL(generic_file_splice_write_nolock);
* generic_file_splice_write - splice data from a pipe to a file * generic_file_splice_write - splice data from a pipe to a file
* @pipe: pipe info * @pipe: pipe info
* @out: file to write to * @out: file to write to
* @ppos: position in @out
* @len: number of bytes to splice * @len: number of bytes to splice
* @flags: splice modifier flags * @flags: splice modifier flags
* *
* Will either move or copy pages (determined by @flags options) from * Description:
* the given pipe inode to the given file. * Will either move or copy pages (determined by @flags options) from
* the given pipe inode to the given file.
* *
*/ */
ssize_t ssize_t
...@@ -886,13 +920,15 @@ EXPORT_SYMBOL(generic_file_splice_write); ...@@ -886,13 +920,15 @@ EXPORT_SYMBOL(generic_file_splice_write);
/** /**
* generic_splice_sendpage - splice data from a pipe to a socket * generic_splice_sendpage - splice data from a pipe to a socket
* @inode: pipe inode * @pipe: pipe to splice from
* @out: socket to write to * @out: socket to write to
* @ppos: position in @out
* @len: number of bytes to splice * @len: number of bytes to splice
* @flags: splice modifier flags * @flags: splice modifier flags
* *
* Will send @len bytes from the pipe to a network socket. No data copying * Description:
* is involved. * Will send @len bytes from the pipe to a network socket. No data copying
* is involved.
* *
*/ */
ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out, ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out,
...@@ -946,8 +982,18 @@ static long do_splice_to(struct file *in, loff_t *ppos, ...@@ -946,8 +982,18 @@ static long do_splice_to(struct file *in, loff_t *ppos,
return in->f_op->splice_read(in, ppos, pipe, len, flags); return in->f_op->splice_read(in, ppos, pipe, len, flags);
} }
/* /**
* Splices from an input file to an actor, using a 'direct' pipe. * splice_direct_to_actor - splices data directly between two non-pipes
* @in: file to splice from
* @sd: actor information on where to splice to
* @actor: handles the data splicing
*
* Description:
* This is a special case helper to splice directly between two
* points, without requiring an explicit pipe. Internally an allocated
* pipe is cached in the process, and reused during the life time of
* that process.
*
*/ */
ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
splice_direct_actor *actor) splice_direct_actor *actor)
...@@ -1077,6 +1123,21 @@ static int direct_splice_actor(struct pipe_inode_info *pipe, ...@@ -1077,6 +1123,21 @@ static int direct_splice_actor(struct pipe_inode_info *pipe,
return do_splice_from(pipe, file, &sd->pos, sd->total_len, sd->flags); return do_splice_from(pipe, file, &sd->pos, sd->total_len, sd->flags);
} }
/**
* do_splice_direct - splices data directly between two files
* @in: file to splice from
* @ppos: input file offset
* @out: file to splice to
* @len: number of bytes to splice
* @flags: splice modifier flags
*
* Description:
* For use by do_sendfile(). splice can easily emulate sendfile, but
* doing it in the application would incur an extra system call
* (splice in + splice out, as compared to just sendfile()). So this helper
* can splice directly through a process-private pipe.
*
*/
long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
size_t len, unsigned int flags) size_t len, unsigned int flags)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment