Merge tag 'for-5.12/block-2021-02-17' of git://git.kernel.dk/linux-block
[linux-2.6-microblaze.git] / fs / splice.c
index 474fb8b..5dbce4d 100644 (file)
@@ -774,11 +774,16 @@ static long do_splice_to(struct file *in, loff_t *ppos,
                         struct pipe_inode_info *pipe, size_t len,
                         unsigned int flags)
 {
+       unsigned int p_space;
        int ret;
 
        if (unlikely(!(in->f_mode & FMODE_READ)))
                return -EBADF;
 
+       /* Don't try to read more the pipe has space for. */
+       p_space = pipe->max_usage - pipe_occupancy(pipe->head, pipe->tail);
+       len = min_t(size_t, len, p_space << PAGE_SHIFT);
+
        ret = rw_verify_area(READ, in, ppos, len);
        if (unlikely(ret < 0))
                return ret;
@@ -859,15 +864,10 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
        WARN_ON_ONCE(!pipe_empty(pipe->head, pipe->tail));
 
        while (len) {
-               unsigned int p_space;
                size_t read_len;
                loff_t pos = sd->pos, prev_pos = pos;
 
-               /* Don't try to read more the pipe has space for. */
-               p_space = pipe->max_usage -
-                       pipe_occupancy(pipe->head, pipe->tail);
-               read_len = min_t(size_t, len, p_space << PAGE_SHIFT);
-               ret = do_splice_to(in, &pos, pipe, read_len, flags);
+               ret = do_splice_to(in, &pos, pipe, len, flags);
                if (unlikely(ret <= 0))
                        goto out_release;
 
@@ -1005,6 +1005,23 @@ static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe,
                               struct pipe_inode_info *opipe,
                               size_t len, unsigned int flags);
 
+long splice_file_to_pipe(struct file *in,
+                        struct pipe_inode_info *opipe,
+                        loff_t *offset,
+                        size_t len, unsigned int flags)
+{
+       long ret;
+
+       pipe_lock(opipe);
+       ret = wait_for_space(opipe, flags);
+       if (!ret)
+               ret = do_splice_to(in, offset, opipe, len, flags);
+       pipe_unlock(opipe);
+       if (ret > 0)
+               wakeup_pipe_readers(opipe);
+       return ret;
+}
+
 /*
  * Determine where to splice to/from.
  */
@@ -1084,20 +1101,7 @@ long do_splice(struct file *in, loff_t *off_in, struct file *out,
                if (out->f_flags & O_NONBLOCK)
                        flags |= SPLICE_F_NONBLOCK;
 
-               pipe_lock(opipe);
-               ret = wait_for_space(opipe, flags);
-               if (!ret) {
-                       unsigned int p_space;
-
-                       /* Don't try to read more the pipe has space for. */
-                       p_space = opipe->max_usage - pipe_occupancy(opipe->head, opipe->tail);
-                       len = min_t(size_t, len, p_space << PAGE_SHIFT);
-
-                       ret = do_splice_to(in, &offset, opipe, len, flags);
-               }
-               pipe_unlock(opipe);
-               if (ret > 0)
-                       wakeup_pipe_readers(opipe);
+               ret = splice_file_to_pipe(in, opipe, &offset, len, flags);
                if (!off_in)
                        in->f_pos = offset;
                else