diff options
-rw-r--r-- | fs/ocfs2/file.c | 8 | ||||
-rw-r--r-- | fs/splice.c | 25 |
2 files changed, 26 insertions, 7 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index a5887df2cd8a..8672b9536039 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -1926,7 +1926,7 @@ static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe, | |||
1926 | out->f_path.dentry->d_name.len, | 1926 | out->f_path.dentry->d_name.len, |
1927 | out->f_path.dentry->d_name.name); | 1927 | out->f_path.dentry->d_name.name); |
1928 | 1928 | ||
1929 | inode_double_lock(inode, pipe->inode); | 1929 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT); |
1930 | 1930 | ||
1931 | ret = ocfs2_rw_lock(inode, 1); | 1931 | ret = ocfs2_rw_lock(inode, 1); |
1932 | if (ret < 0) { | 1932 | if (ret < 0) { |
@@ -1941,12 +1941,16 @@ static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe, | |||
1941 | goto out_unlock; | 1941 | goto out_unlock; |
1942 | } | 1942 | } |
1943 | 1943 | ||
1944 | if (pipe->inode) | ||
1945 | mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_CHILD); | ||
1944 | ret = generic_file_splice_write_nolock(pipe, out, ppos, len, flags); | 1946 | ret = generic_file_splice_write_nolock(pipe, out, ppos, len, flags); |
1947 | if (pipe->inode) | ||
1948 | mutex_unlock(&pipe->inode->i_mutex); | ||
1945 | 1949 | ||
1946 | out_unlock: | 1950 | out_unlock: |
1947 | ocfs2_rw_unlock(inode, 1); | 1951 | ocfs2_rw_unlock(inode, 1); |
1948 | out: | 1952 | out: |
1949 | inode_double_unlock(inode, pipe->inode); | 1953 | mutex_unlock(&inode->i_mutex); |
1950 | 1954 | ||
1951 | mlog_exit(ret); | 1955 | mlog_exit(ret); |
1952 | return ret; | 1956 | return ret; |
diff --git a/fs/splice.c b/fs/splice.c index dd727d43e5b7..c18aa7e03e2b 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -737,10 +737,19 @@ ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, | |||
737 | * ->write_end. Most of the time, these expect i_mutex to | 737 | * ->write_end. Most of the time, these expect i_mutex to |
738 | * be held. Since this may result in an ABBA deadlock with | 738 | * be held. Since this may result in an ABBA deadlock with |
739 | * pipe->inode, we have to order lock acquiry here. | 739 | * pipe->inode, we have to order lock acquiry here. |
740 | * | ||
741 | * Outer lock must be inode->i_mutex, as pipe_wait() will | ||
742 | * release and reacquire pipe->inode->i_mutex, AND inode must | ||
743 | * never be a pipe. | ||
740 | */ | 744 | */ |
741 | inode_double_lock(inode, pipe->inode); | 745 | WARN_ON(S_ISFIFO(inode->i_mode)); |
746 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT); | ||
747 | if (pipe->inode) | ||
748 | mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_CHILD); | ||
742 | ret = __splice_from_pipe(pipe, &sd, actor); | 749 | ret = __splice_from_pipe(pipe, &sd, actor); |
743 | inode_double_unlock(inode, pipe->inode); | 750 | if (pipe->inode) |
751 | mutex_unlock(&pipe->inode->i_mutex); | ||
752 | mutex_unlock(&inode->i_mutex); | ||
744 | 753 | ||
745 | return ret; | 754 | return ret; |
746 | } | 755 | } |
@@ -831,11 +840,17 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, | |||
831 | }; | 840 | }; |
832 | ssize_t ret; | 841 | ssize_t ret; |
833 | 842 | ||
834 | inode_double_lock(inode, pipe->inode); | 843 | WARN_ON(S_ISFIFO(inode->i_mode)); |
844 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT); | ||
835 | ret = file_remove_suid(out); | 845 | ret = file_remove_suid(out); |
836 | if (likely(!ret)) | 846 | if (likely(!ret)) { |
847 | if (pipe->inode) | ||
848 | mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_CHILD); | ||
837 | ret = __splice_from_pipe(pipe, &sd, pipe_to_file); | 849 | ret = __splice_from_pipe(pipe, &sd, pipe_to_file); |
838 | inode_double_unlock(inode, pipe->inode); | 850 | if (pipe->inode) |
851 | mutex_unlock(&pipe->inode->i_mutex); | ||
852 | } | ||
853 | mutex_unlock(&inode->i_mutex); | ||
839 | if (ret > 0) { | 854 | if (ret > 0) { |
840 | unsigned long nr_pages; | 855 | unsigned long nr_pages; |
841 | 856 | ||