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*pipe

pipe to fill

structsplice_pipe_desc*spd

data to fill

Description

spd contains a map of pages and len/offset tuples, along withthestructpipe_buf_operations associated 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*in

The file to read from

loff_t*ppos

Pointer to the file position to read from

structpipe_inode_info*pipe

The pipe to splice into

size_tlen

The amount to splice

unsignedintflags

The 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*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 singlestructpipe_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.

intsplice_from_pipe_next(structpipe_inode_info*pipe,structsplice_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.

voidsplice_from_pipe_begin(structsplice_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.

voidsplice_from_pipe_end(structpipe_inode_info*pipe,structsplice_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,structsplice_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 singlestructpipe_buffer tothe 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*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_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*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_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*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_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*in

File to splice from

loff_t*ppos

Input file offset

structpipe_inode_info*pipe

Pipe to splice to

size_tlen

Number of bytes to splice

unsignedintflags

Splice 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*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.

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*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 bydo_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 forcopy_file_range()

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

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

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.

unionpipe_index

pipe indeces

Definition:

union pipe_index {    unsigned long head_tail;    struct {        pipe_index_t head;        pipe_index_t tail;    };};

Members

head_tail

unsigned longunionofhead andtail

{unnamed_struct}

anonymous

head

The point of buffer production

tail

The 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

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

pipe_index

the pipe indeces

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)

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 ofstructfile referring this pipe (protected by ->i_lock)

r_counter

reader counter

w_counter

writer counter

poll_usage

is this pipe used for epoll, which has crazy wakeups?

note_loss

The next read() should insert a data-lost message

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

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*pipe

The 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

unsignedinthead

The pipe ring head pointer

unsignedinttail

The pipe ring tail pointer

boolpipe_empty(unsignedinthead,unsignedinttail)

Return true if the pipe is empty

Parameters

unsignedinthead

The pipe ring head pointer

unsignedinttail

The pipe ring tail pointer

boolpipe_full(unsignedinthead,unsignedinttail,unsignedintlimit)

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.

boolpipe_is_full(conststructpipe_inode_info*pipe)

Return true if the pipe is full

Parameters

conststructpipe_inode_info*pipe

the pipe

boolpipe_is_empty(conststructpipe_inode_info*pipe)

Return true if the pipe is empty

Parameters

conststructpipe_inode_info*pipe

the pipe

unsignedintpipe_buf_usage(conststructpipe_inode_info*pipe)

Return how many pipe buffers are in use

Parameters

conststructpipe_inode_info*pipe

the 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*pipe

The pipe to access

unsignedintslot

The 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*pipe

The pipe to access

boolpipe_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.

voidpipe_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

intpipe_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

boolpipe_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

boolgeneric_pipe_buf_try_steal(structpipe_inode_info*pipe,structpipe_buffer*buf)

attempt to take ownership of apipe_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 thestructpage attached 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 astructpipe_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 inthetee() 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 astructpipe_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.