splice and pipes¶
splice API¶
splice is a method for moving blocks of data around inside the kernel,without continually transferring them between the kernel and user space.
- ssize_t
splice_to_pipe(structpipe_inode_info * pipe, struct splice_pipe_desc * spd)¶ fill passed data into a pipe
Parameters
structpipe_inode_info*pipe- pipe to fill
structsplice_pipe_desc*spd- data to fill
Description
spd contains a map of pages and len/offset tuples, along withthe struct pipe_buf_operations associated with these pages. Thisfunction will link that data to the pipe.
- ssize_t
generic_file_splice_read(struct file * in, loff_t * ppos, structpipe_inode_info * pipe, size_t len, unsigned int flags)¶ splice data from file to a pipe
Parameters
structfile*in- file to splice from
loff_t*ppos- position inin
structpipe_inode_info*pipe- pipe to splice to
size_tlen- number of bytes to splice
unsignedintflags- splice modifier flags
Description
Will read pages from given file and fill them into a pipe. Can beused as long as it has more or less sane ->read_iter().
- int
splice_from_pipe_feed(structpipe_inode_info * pipe, struct splice_desc * sd, splice_actor * actor)¶ feed available data from a pipe to a file
Parameters
structpipe_inode_info*pipe- pipe to splice from
structsplice_desc*sd- information toactor
splice_actor*actor- handler that splices the data
Description
This function loops over the pipe and callsactor to do theactual moving of a single struct pipe_buffer to the desireddestination. It returns when there’s no more buffers left inthe pipe or if the requested number of bytes (sd->total_len)have been copied. It returns a positive number (one) if thepipe needs to be filled with more data, zero if the requirednumber of bytes have been copied and -errno on error.
This, together with splice_from_pipe_{begin,end,next}, may beused to implement the functionality of
__splice_from_pipe()whenlocking is required around copying the pipe buffers to thedestination.
- int
splice_from_pipe_next(structpipe_inode_info * pipe, struct splice_desc * sd)¶ wait for some data to splice from
Parameters
structpipe_inode_info*pipe- pipe to splice from
structsplice_desc*sd- information about the splice operation
Description
This function will wait for some data and return a positivevalue (one) if pipe buffers are available. It will return zeroor -errno if no more data needs to be spliced.
- void
splice_from_pipe_begin(struct splice_desc * sd)¶ start splicing from pipe
Parameters
structsplice_desc*sd- information about the splice operation
Description
This function should be called before a loop containingsplice_from_pipe_next()andsplice_from_pipe_feed()toinitialize the necessary fields ofsd.
- void
splice_from_pipe_end(structpipe_inode_info * pipe, struct splice_desc * sd)¶ finish splicing from pipe
Parameters
structpipe_inode_info*pipe- pipe to splice from
structsplice_desc*sd- information about the splice operation
Description
This function will wake up pipe writers if necessary. It shouldbe called after a loop containingsplice_from_pipe_next()andsplice_from_pipe_feed().
- ssize_t
__splice_from_pipe(structpipe_inode_info * pipe, struct splice_desc * sd, splice_actor * actor)¶ splice data from a pipe to given actor
Parameters
structpipe_inode_info*pipe- pipe to splice from
structsplice_desc*sd- information toactor
splice_actor*actor- handler that splices the data
Description
This function does little more than loop over the pipe and callactor to do the actual moving of a single struct pipe_buffer tothe desired destination. See pipe_to_file, pipe_to_sendpage, orpipe_to_user.
- ssize_t
splice_from_pipe(structpipe_inode_info * pipe, struct file * out, loff_t * ppos, size_t len, unsigned int flags, splice_actor * actor)¶ splice data from a pipe to a file
Parameters
structpipe_inode_info*pipe- pipe to splice from
structfile*out- file to splice to
loff_t*ppos- position inout
size_tlen- how many bytes to splice
unsignedintflags- splice modifier flags
splice_actor*actor- handler that splices the data
Description
See __splice_from_pipe. This function locks the pipe inode,otherwise it’s identical to__splice_from_pipe().
- ssize_t
iter_file_splice_write(structpipe_inode_info * pipe, struct file * out, loff_t * ppos, size_t len, unsigned int flags)¶ splice data from a pipe to a file
Parameters
structpipe_inode_info*pipe- pipe info
structfile*out- file to write to
loff_t*ppos- position inout
size_tlen- number of bytes to splice
unsignedintflags- splice modifier flags
Description
Will either move or copy pages (determined byflags options) fromthe given pipe inode to the given file.This one is ->write_iter-based.
- ssize_t
generic_splice_sendpage(structpipe_inode_info * pipe, struct file * out, loff_t * ppos, size_t len, unsigned int flags)¶ splice data from a pipe to a socket
Parameters
structpipe_inode_info*pipe- pipe to splice from
structfile*out- socket to write to
loff_t*ppos- position inout
size_tlen- number of bytes to splice
unsignedintflags- splice modifier flags
Description
Will sendlen bytes from the pipe to a network socket. No data copyingis involved.
- ssize_t
splice_direct_to_actor(struct file * in, struct splice_desc * sd, splice_direct_actor * actor)¶ splices data directly between two non-pipes
Parameters
structfile*in- file to splice from
structsplice_desc*sd- actor information on where to splice to
splice_direct_actor*actor- handles the data splicing
Description
This is a special case helper to splice directly between twopoints, without requiring an explicit pipe. Internally an allocatedpipe is cached in the process, and reused during the lifetime ofthat process.
- long
do_splice_direct(struct file * in, loff_t * ppos, struct file * out, loff_t * opos, size_t len, unsigned int flags)¶ splices data directly between two files
Parameters
structfile*in- file to splice from
loff_t*ppos- input file offset
structfile*out- file to splice to
loff_t*opos- output file offset
size_tlen- number of bytes to splice
unsignedintflags- splice modifier flags
Description
For use by do_sendfile(). splice can easily emulate sendfile, butdoing it in the application would incur an extra system call(splice in + splice out, as compared to just sendfile()). So this helpercan splice directly through a process-private pipe.
pipes API¶
Pipe interfaces are all for in-kernel (builtin image) use. They are notexported for use by modules.
- struct
pipe_buffer¶ a linux kernel pipe buffer
Definition
struct pipe_buffer { struct page *page; unsigned int offset, len; const struct pipe_buf_operations *ops; unsigned int flags; unsigned long private;};Members
page- the page containing the data for the pipe buffer
offset- offset of data inside thepage
len- length of data inside thepage
ops- operations associated with this buffer. Seepipe_buf_operations.
flags- pipe buffer flags. See above.
private- private data owned by the ops.
- struct
pipe_inode_info¶ a linux kernel pipe
Definition
struct pipe_inode_info { struct mutex mutex; wait_queue_head_t rd_wait, wr_wait; unsigned int head; unsigned int tail; unsigned int max_usage; unsigned int ring_size;#ifdef CONFIG_WATCH_QUEUE; bool note_loss;#endif; unsigned int nr_accounted; unsigned int readers; unsigned int writers; unsigned int files; unsigned int r_counter; unsigned int w_counter; struct page *tmp_page; struct fasync_struct *fasync_readers; struct fasync_struct *fasync_writers; struct pipe_buffer *bufs; struct user_struct *user;#ifdef CONFIG_WATCH_QUEUE; struct watch_queue *watch_queue;#endif;};Members
mutex- mutex protecting the whole thing
rd_wait- reader wait point in case of empty pipe
wr_wait- writer wait point in case of full pipe
head- The point of buffer production
tail- The point of buffer consumption
max_usage- The maximum number of slots that may be used in the ring
ring_size- total number of buffers (should be a power of 2)
note_loss- The next read() should insert a data-lost message
nr_accounted- The amount this pipe accounts for in user->pipe_bufs
readers- number of current readers of this pipe
writers- number of current writers of this pipe
files- number of struct file referring this pipe (protected by ->i_lock)
r_counter- reader counter
w_counter- writer counter
tmp_page- cached released page
fasync_readers- reader side fasync
fasync_writers- writer side fasync
bufs- the circular array of pipe buffers
user- the user who created this pipe
watch_queue- If this pipe is a watch_queue, this is the stuff for that
- bool
pipe_empty(unsigned int head, unsigned int tail)¶ Return true if the pipe is empty
Parameters
unsignedinthead- The pipe ring head pointer
unsignedinttail- The pipe ring tail pointer
- unsigned int
pipe_occupancy(unsigned int head, unsigned int tail)¶ Return number of slots used in the pipe
Parameters
unsignedinthead- The pipe ring head pointer
unsignedinttail- The pipe ring tail pointer
- bool
pipe_full(unsigned int head, unsigned int tail, unsigned int limit)¶ Return true if the pipe is full
Parameters
unsignedinthead- The pipe ring head pointer
unsignedinttail- The pipe ring tail pointer
unsignedintlimit- The maximum amount of slots available.
- unsigned int
pipe_space_for_user(unsigned int head, unsigned int tail, structpipe_inode_info * pipe)¶ Return number of slots available to userspace
Parameters
unsignedinthead- The pipe ring head pointer
unsignedinttail- The pipe ring tail pointer
structpipe_inode_info*pipe- The pipe info structure
- bool
pipe_buf_get(structpipe_inode_info * pipe, structpipe_buffer * buf)¶ get a reference to a pipe_buffer
Parameters
structpipe_inode_info*pipe- the pipe that the buffer belongs to
structpipe_buffer*buf- the buffer to get a reference to
Return
true if the reference was successfully obtained.
- void
pipe_buf_release(structpipe_inode_info * pipe, structpipe_buffer * buf)¶ put a reference to a pipe_buffer
Parameters
structpipe_inode_info*pipe- the pipe that the buffer belongs to
structpipe_buffer*buf- the buffer to put a reference to
- int
pipe_buf_confirm(structpipe_inode_info * pipe, structpipe_buffer * buf)¶ verify contents of the pipe buffer
Parameters
structpipe_inode_info*pipe- the pipe that the buffer belongs to
structpipe_buffer*buf- the buffer to confirm
- bool
pipe_buf_try_steal(structpipe_inode_info * pipe, structpipe_buffer * buf)¶ attempt to take ownership of a pipe_buffer
Parameters
structpipe_inode_info*pipe- the pipe that the buffer belongs to
structpipe_buffer*buf- the buffer to attempt to steal
- bool
generic_pipe_buf_try_steal(structpipe_inode_info * pipe, structpipe_buffer * buf)¶ attempt to take ownership of a
pipe_buffer
Parameters
structpipe_inode_info*pipe- the pipe that the buffer belongs to
structpipe_buffer*buf- the buffer to attempt to steal
Description
This function attempts to steal thestructpageattached tobuf. If successful, this function returns 0 and returns withthe page locked. The caller may then reuse the page for whateverhe wishes; the typical use is insertion into a different filepage cache.
- bool
generic_pipe_buf_get(structpipe_inode_info * pipe, structpipe_buffer * buf)¶ get a reference to a
structpipe_buffer
Parameters
structpipe_inode_info*pipe- the pipe that the buffer belongs to
structpipe_buffer*buf- the buffer to get a reference to
Description
This function grabs an extra reference tobuf. It’s used inin the tee() system call, when we duplicate the buffers in onepipe into another.
- void
generic_pipe_buf_release(structpipe_inode_info * pipe, structpipe_buffer * buf)¶ put a reference to a
structpipe_buffer
Parameters
structpipe_inode_info*pipe- the pipe that the buffer belongs to
structpipe_buffer*buf- the buffer to put a reference to
Description
This function releases a reference tobuf.