splice: implement pipe to pipe splicing
authorMiklos Szeredi <miklos@szeredi.hu>
Thu, 7 May 2009 13:37:35 +0000 (15:37 +0200)
committerJens Axboe <jens.axboe@oracle.com>
Mon, 11 May 2009 12:13:09 +0000 (14:13 +0200)
commit7c77f0b3f9208c339a4b40737bb2cb0f0319bb8d
treecf45bc6afaa4bab28275b5aefc903f0112545965
parentb1f744937f1be3e6d3009382a755679133cf782d
splice: implement pipe to pipe splicing

Allow splice(2) to work when both the input and the output is a pipe.

Based on the impementation of the tee(2) syscall, but instead of
duplicating the buffer references move the buffers from the input pipe
to the output pipe.

Moving the whole buffer only succeeds if the full length of the buffer
is spliced.  Otherwise duplicate the buffer, just like tee(2), set the
length of the output buffer and advance the offset on the input
buffer.

Since splice is operating on two pipes, special care needs to be taken
with locking to prevent AN ABBA deadlock.  Again this is done
similarly to the tee(2) syscall, first preparing the input and output
pipes so there's data to consume and space for that data, and then
doing the move operation while holding both locks.

If other processes are doing I/O on the same pipes parallel to the
splice, then by the time both inodes are locked there might be no
buffers left to move, or no space to move them to.  In this case retry
the whole operation, including the preparation phase.  This could lead
to starvation, but I'm not sure if that's serious enough to worry
about.

Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
fs/splice.c