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_tsplice_to_pipe(structpipe_inode_info*pipe,structsplice_pipe_desc*spd)¶
fill passed data into a pipe
Parameters
structpipe_inode_info*pipepipe to fill
structsplice_pipe_desc*spddata to fill
Description
spd contains a map of pages and len/offset tuples, along withthe
structpipe_buf_operationsassociated with these pages. Thisfunction will link that data to the pipe.
- ssize_tcopy_splice_read(structfile*in,loff_t*ppos,structpipe_inode_info*pipe,size_tlen,unsignedintflags)¶
Copy data from a file and splice the copy into a pipe
Parameters
structfile*inThe file to read from
loff_t*pposPointer to the file position to read from
structpipe_inode_info*pipeThe pipe to splice into
size_tlenThe amount to splice
unsignedintflagsThe SPLICE_F_* flags
Description
This function allocates a bunch of pages sufficient to hold the requestedamount of data (but limited by the remaining pipe capacity), passes it tothe file’s ->read_iter() to read into and then splices the used pages intothe pipe.
Return
On success, the number of bytes read will be returned and*pposwill be updated if appropriate; 0 will be returned if there is no more datato be read; -EAGAIN will be returned if the pipe had no space, and someother negative error code will be returned on error. A short read may occurif the pipe has insufficient space, we reach the end of the data or we hit ahole.
- intsplice_from_pipe_feed(structpipe_inode_info*pipe,structsplice_desc*sd,splice_actor*actor)¶
feed available data from a pipe to a file
Parameters
structpipe_inode_info*pipepipe to splice from
structsplice_desc*sdinformation toactor
splice_actor*actorhandler that splices the data
Description
This function loops over the pipe and callsactor to do theactual moving of a single
structpipe_bufferto 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.
- intsplice_from_pipe_next(structpipe_inode_info*pipe,structsplice_desc*sd)¶
wait for some data to splice from
Parameters
structpipe_inode_info*pipepipe to splice from
structsplice_desc*sdinformation 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.
- voidsplice_from_pipe_begin(structsplice_desc*sd)¶
start splicing from pipe
Parameters
structsplice_desc*sdinformation about the splice operation
Description
This function should be called before a loop containing
splice_from_pipe_next()andsplice_from_pipe_feed()toinitialize the necessary fields ofsd.
- voidsplice_from_pipe_end(structpipe_inode_info*pipe,structsplice_desc*sd)¶
finish splicing from pipe
Parameters
structpipe_inode_info*pipepipe to splice from
structsplice_desc*sdinformation about the splice operation
Description
This function will wake up pipe writers if necessary. It shouldbe called after a loop containing
splice_from_pipe_next()andsplice_from_pipe_feed().
- ssize_t__splice_from_pipe(structpipe_inode_info*pipe,structsplice_desc*sd,splice_actor*actor)¶
splice data from a pipe to given actor
Parameters
structpipe_inode_info*pipepipe to splice from
structsplice_desc*sdinformation toactor
splice_actor*actorhandler 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
structpipe_buffertothe desired destination. See pipe_to_file, pipe_to_sendmsg, orpipe_to_user.
- ssize_tsplice_from_pipe(structpipe_inode_info*pipe,structfile*out,loff_t*ppos,size_tlen,unsignedintflags,splice_actor*actor)¶
splice data from a pipe to a file
Parameters
structpipe_inode_info*pipepipe to splice from
structfile*outfile to splice to
loff_t*pposposition inout
size_tlenhow many bytes to splice
unsignedintflagssplice modifier flags
splice_actor*actorhandler that splices the data
Description
See __splice_from_pipe. This function locks the pipe inode,otherwise it’s identical to
__splice_from_pipe().
- ssize_titer_file_splice_write(structpipe_inode_info*pipe,structfile*out,loff_t*ppos,size_tlen,unsignedintflags)¶
splice data from a pipe to a file
Parameters
structpipe_inode_info*pipepipe info
structfile*outfile to write to
loff_t*pposposition inout
size_tlennumber of bytes to splice
unsignedintflagssplice 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_tsplice_to_socket(structpipe_inode_info*pipe,structfile*out,loff_t*ppos,size_tlen,unsignedintflags)¶
splice data from a pipe to a socket
Parameters
structpipe_inode_info*pipepipe to splice from
structfile*outsocket to write to
loff_t*pposposition inout
size_tlennumber of bytes to splice
unsignedintflagssplice modifier flags
Description
Will sendlen bytes from the pipe to a network socket. No data copyingis involved.
- ssize_tvfs_splice_read(structfile*in,loff_t*ppos,structpipe_inode_info*pipe,size_tlen,unsignedintflags)¶
Read data from a file and splice it into a pipe
Parameters
structfile*inFile to splice from
loff_t*pposInput file offset
structpipe_inode_info*pipePipe to splice to
size_tlenNumber of bytes to splice
unsignedintflagsSplice modifier flags (SPLICE_F_*)
Description
Splice the requested amount of data from the input file to the pipe. Thisis synchronous as the caller must hold the pipe lock across the entireoperation.
If successful, it returns the amount of data spliced, 0 if it hit the EOF ora hole and a negative error code otherwise.
- ssize_tsplice_direct_to_actor(structfile*in,structsplice_desc*sd,splice_direct_actor*actor)¶
splices data directly between two non-pipes
Parameters
structfile*infile to splice from
structsplice_desc*sdactor information on where to splice to
splice_direct_actor*actorhandles 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.
- ssize_tdo_splice_direct(structfile*in,loff_t*ppos,structfile*out,loff_t*opos,size_tlen,unsignedintflags)¶
splices data directly between two files
Parameters
structfile*infile to splice from
loff_t*pposinput file offset
structfile*outfile to splice to
loff_t*oposoutput file offset
size_tlennumber of bytes to splice
unsignedintflagssplice 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 justsendfile()). So this helpercan splice directly through a process-private pipe.
Callers already calledrw_verify_area() on the entire range.
- ssize_tsplice_file_range(structfile*in,loff_t*ppos,structfile*out,loff_t*opos,size_tlen)¶
splices data between two files for
copy_file_range()
Parameters
structfile*infile to splice from
loff_t*pposinput file offset
structfile*outfile to splice to
loff_t*oposoutput file offset
size_tlennumber of bytes to splice
Description
For use by ->
copy_file_range()methods.Likedo_splice_direct(), butvfs_copy_file_range()already holdsstart_file_write()onout file.
Callers already calledrw_verify_area() on the entire range.
pipes API¶
Pipe interfaces are all for in-kernel (builtin image) use. They are notexported for use by modules.
- structpipe_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
pagethe page containing the data for the pipe buffer
offsetoffset of data inside thepage
lenlength of data inside thepage
opsoperations associated with this buffer. Seepipe_buf_operations.
flagspipe buffer flags. See above.
privateprivate data owned by the ops.
- unionpipe_index¶
pipe indeces
Definition:
union pipe_index { unsigned long head_tail; struct { pipe_index_t head; pipe_index_t tail; };};Members
head_tailunsigned long
unionofhead andtail{unnamed_struct}anonymous
headThe point of buffer production
tailThe point of buffer consumption
- structpipe_inode_info¶
a linux kernel pipe
Definition:
struct pipe_inode_info { struct mutex mutex; wait_queue_head_t rd_wait, wr_wait; union pipe_index; unsigned int max_usage; unsigned int ring_size; unsigned int nr_accounted; unsigned int readers; unsigned int writers; unsigned int files; unsigned int r_counter; unsigned int w_counter; bool poll_usage;#ifdef CONFIG_WATCH_QUEUE; bool note_loss;#endif; struct page *tmp_page[2]; 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
mutexmutex protecting the whole thing
rd_waitreader wait point in case of empty pipe
wr_waitwriter wait point in case of full pipe
pipe_indexthe pipe indeces
max_usageThe maximum number of slots that may be used in the ring
ring_sizetotal number of buffers (should be a power of 2)
nr_accountedThe amount this pipe accounts for in user->pipe_bufs
readersnumber of current readers of this pipe
writersnumber of current writers of this pipe
filesnumber of
structfilereferring this pipe (protected by ->i_lock)r_counterreader counter
w_counterwriter counter
poll_usageis this pipe used for epoll, which has crazy wakeups?
note_lossThe next read() should insert a data-lost message
tmp_pagecached released page
fasync_readersreader side fasync
fasync_writerswriter side fasync
bufsthe circular array of pipe buffers
userthe user who created this pipe
watch_queueIf this pipe is a watch_queue, this is the stuff for that
- boolpipe_has_watch_queue(conststructpipe_inode_info*pipe)¶
Check whether the pipe is a watch_queue, i.e. it was created with O_NOTIFICATION_PIPE
Parameters
conststructpipe_inode_info*pipeThe pipe to check
Return
true if pipe is a watch queue, false otherwise.
- unsignedintpipe_occupancy(unsignedinthead,unsignedinttail)¶
Return number of slots used in the pipe
Parameters
unsignedintheadThe pipe ring head pointer
unsignedinttailThe pipe ring tail pointer
- boolpipe_empty(unsignedinthead,unsignedinttail)¶
Return true if the pipe is empty
Parameters
unsignedintheadThe pipe ring head pointer
unsignedinttailThe pipe ring tail pointer
- boolpipe_full(unsignedinthead,unsignedinttail,unsignedintlimit)¶
Return true if the pipe is full
Parameters
unsignedintheadThe pipe ring head pointer
unsignedinttailThe pipe ring tail pointer
unsignedintlimitThe maximum amount of slots available.
- boolpipe_is_full(conststructpipe_inode_info*pipe)¶
Return true if the pipe is full
Parameters
conststructpipe_inode_info*pipethe pipe
- boolpipe_is_empty(conststructpipe_inode_info*pipe)¶
Return true if the pipe is empty
Parameters
conststructpipe_inode_info*pipethe pipe
- unsignedintpipe_buf_usage(conststructpipe_inode_info*pipe)¶
Return how many pipe buffers are in use
Parameters
conststructpipe_inode_info*pipethe pipe
- structpipe_buffer*pipe_buf(conststructpipe_inode_info*pipe,unsignedintslot)¶
Return the pipe buffer for the specified slot in the pipe ring
Parameters
conststructpipe_inode_info*pipeThe pipe to access
unsignedintslotThe slot of interest
- structpipe_buffer*pipe_head_buf(conststructpipe_inode_info*pipe)¶
Return the pipe buffer at the head of the pipe ring
Parameters
conststructpipe_inode_info*pipeThe pipe to access
- boolpipe_buf_get(structpipe_inode_info*pipe,structpipe_buffer*buf)¶
get a reference to a pipe_buffer
Parameters
structpipe_inode_info*pipethe pipe that the buffer belongs to
structpipe_buffer*bufthe buffer to get a reference to
Return
true if the reference was successfully obtained.
- voidpipe_buf_release(structpipe_inode_info*pipe,structpipe_buffer*buf)¶
put a reference to a pipe_buffer
Parameters
structpipe_inode_info*pipethe pipe that the buffer belongs to
structpipe_buffer*bufthe buffer to put a reference to
- intpipe_buf_confirm(structpipe_inode_info*pipe,structpipe_buffer*buf)¶
verify contents of the pipe buffer
Parameters
structpipe_inode_info*pipethe pipe that the buffer belongs to
structpipe_buffer*bufthe buffer to confirm
- boolpipe_buf_try_steal(structpipe_inode_info*pipe,structpipe_buffer*buf)¶
attempt to take ownership of a pipe_buffer
Parameters
structpipe_inode_info*pipethe pipe that the buffer belongs to
structpipe_buffer*bufthe buffer to attempt to steal
- boolgeneric_pipe_buf_try_steal(structpipe_inode_info*pipe,structpipe_buffer*buf)¶
attempt to take ownership of a
pipe_buffer
Parameters
structpipe_inode_info*pipethe pipe that the buffer belongs to
structpipe_buffer*bufthe buffer to attempt to steal
Description
This function attempts to steal the
structpageattached 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.
- boolgeneric_pipe_buf_get(structpipe_inode_info*pipe,structpipe_buffer*buf)¶
get a reference to a
structpipe_buffer
Parameters
structpipe_inode_info*pipethe pipe that the buffer belongs to
structpipe_buffer*bufthe buffer to get a reference to
Description
This function grabs an extra reference tobuf. It’s used inthe
tee()system call, when we duplicate the buffers in onepipe into another.
- voidgeneric_pipe_buf_release(structpipe_inode_info*pipe,structpipe_buffer*buf)¶
put a reference to a
structpipe_buffer
Parameters
structpipe_inode_info*pipethe pipe that the buffer belongs to
structpipe_buffer*bufthe buffer to put a reference to
Description
This function releases a reference tobuf.