• M
    splice: implement pipe to pipe splicing · 7c77f0b3
    Miklos Szeredi 提交于
    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: NMiklos Szeredi <mszeredi@suse.cz>
    Signed-off-by: NJens Axboe <jens.axboe@oracle.com>
    7c77f0b3
splice.c 42.6 KB