aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/splice.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/fs/splice.c b/fs/splice.c
index 349576b2c75a..a1f595b9db40 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -895,17 +895,29 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
895 }; 895 };
896 ssize_t ret; 896 ssize_t ret;
897 897
898 WARN_ON(S_ISFIFO(inode->i_mode)); 898 if (pipe->inode)
899 mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT); 899 mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_PARENT);
900 ret = file_remove_suid(out); 900
901 if (likely(!ret)) { 901 splice_from_pipe_begin(&sd);
902 if (pipe->inode) 902 do {
903 mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_CHILD); 903 ret = splice_from_pipe_next(pipe, &sd);
904 ret = __splice_from_pipe(pipe, &sd, pipe_to_file); 904 if (ret <= 0)
905 if (pipe->inode) 905 break;
906 mutex_unlock(&pipe->inode->i_mutex); 906
907 } 907 mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD);
908 mutex_unlock(&inode->i_mutex); 908 ret = file_remove_suid(out);
909 if (!ret)
910 ret = splice_from_pipe_feed(pipe, &sd, pipe_to_file);
911 mutex_unlock(&inode->i_mutex);
912 } while (ret > 0);
913 splice_from_pipe_end(pipe, &sd);
914
915 if (pipe->inode)
916 mutex_unlock(&pipe->inode->i_mutex);
917
918 if (sd.num_spliced)
919 ret = sd.num_spliced;
920
909 if (ret > 0) { 921 if (ret > 0) {
910 unsigned long nr_pages; 922 unsigned long nr_pages;
911 923