• Miklos Szeredi's avatar
    splice: fix deadlock in splicing to file · 7bfac9ec
    Miklos Szeredi authored
    There's a possible deadlock in generic_file_splice_write(),
    splice_from_pipe() and ocfs2_file_splice_write():
    
     - task A calls generic_file_splice_write()
     - this calls inode_double_lock(), which locks i_mutex on both
       pipe->inode and target inode
     - ordering depends on inode pointers, can happen that pipe->inode is
       locked first
     - __splice_from_pipe() needs more data, calls pipe_wait()
     - this releases lock on pipe->inode, goes to interruptible sleep
     - task B calls generic_file_splice_write(), similarly to the first
     - this locks pipe->inode, then tries to lock inode, but that is
       already held by task A
     - task A is interrupted, it tries to lock pipe->inode, but fails, as
       it is already held by task B
     - ABBA deadlock
    
    Fix this by explicitly ordering locks: the outer lock must be on
    target inode and the inner lock (which is later unlocked and relocked)
    must be on pipe->inode.  This is OK, pipe inodes and target inodes
    form two nonoverlapping sets, generic_file_splice_write() and friends
    are not called with a target which is a pipe.
    Signed-off-by: default avatarMiklos Szeredi <mszeredi@suse.cz>
    Acked-by: default avatarMark Fasheh <mfasheh@suse.com>
    Acked-by: default avatarJens Axboe <jens.axboe@oracle.com>
    Cc: stable@kernel.org
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    7bfac9ec
splice.c 39.4 KB