tools headers UAPI: Sync openat2.h with the kernel sources
[linux-2.6-microblaze.git] / fs / read_write.c
index 75f764b..9db7adf 100644 (file)
@@ -1188,6 +1188,7 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
 {
        struct fd in, out;
        struct inode *in_inode, *out_inode;
+       struct pipe_inode_info *opipe;
        loff_t pos;
        loff_t out_pos;
        ssize_t retval;
@@ -1228,9 +1229,6 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
        in_inode = file_inode(in.file);
        out_inode = file_inode(out.file);
        out_pos = out.file->f_pos;
-       retval = rw_verify_area(WRITE, out.file, &out_pos, count);
-       if (retval < 0)
-               goto fput_out;
 
        if (!max)
                max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);
@@ -1253,9 +1251,18 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
        if (in.file->f_flags & O_NONBLOCK)
                fl = SPLICE_F_NONBLOCK;
 #endif
-       file_start_write(out.file);
-       retval = do_splice_direct(in.file, &pos, out.file, &out_pos, count, fl);
-       file_end_write(out.file);
+       opipe = get_pipe_info(out.file, true);
+       if (!opipe) {
+               retval = rw_verify_area(WRITE, out.file, &out_pos, count);
+               if (retval < 0)
+                       goto fput_out;
+               file_start_write(out.file);
+               retval = do_splice_direct(in.file, &pos, out.file, &out_pos,
+                                         count, fl);
+               file_end_write(out.file);
+       } else {
+               retval = splice_file_to_pipe(in.file, opipe, &pos, count, fl);
+       }
 
        if (retval > 0) {
                add_rchar(current, retval);