summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@suse.cz>2009-04-07 16:25:02 +0000
committerGreg Kroah-Hartman <gregkh@suse.de>2009-05-02 10:24:09 -0700
commitd2c1b09939cc84c2ac57e2e8c4c85ec54ab9501c (patch)
treee27b173cd8652085ce74a5b299f4d6f7fb0380dd /sound
parentfe8c4bd76af855702ded3a33fae1020f0bc8a533 (diff)
splice: fix deadlock in splicing to file
upstream commit: 7bfac9ecf0585962fe13584f5cf526d8c8e76f17 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: Miklos Szeredi <mszeredi@suse.cz> Acked-by: Mark Fasheh <mfasheh@suse.com> Acked-by: Jens Axboe <jens.axboe@oracle.com> Cc: stable@kernel.org Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Chris Wright <chrisw@sous-sol.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'sound')
0 files changed, 0 insertions, 0 deletions