do_splice_to(): move the logics for limiting the read length in

Both callers have the identical logics limiting the amount of
data we try to read into pipe - no more than would fit into
that pipe.  Move that into do_splice_to() itself.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Al Viro 2021-01-24 23:49:04 -05:00
parent 5c8fe583cc
commit 313d64a35d

View File

@ -771,11 +771,16 @@ static long do_splice_to(struct file *in, loff_t *ppos,
struct pipe_inode_info *pipe, size_t len, struct pipe_inode_info *pipe, size_t len,
unsigned int flags) unsigned int flags)
{ {
unsigned int p_space;
int ret; int ret;
if (unlikely(!(in->f_mode & FMODE_READ))) if (unlikely(!(in->f_mode & FMODE_READ)))
return -EBADF; 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); ret = rw_verify_area(READ, in, ppos, len);
if (unlikely(ret < 0)) if (unlikely(ret < 0))
return ret; return ret;
@ -856,15 +861,10 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
WARN_ON_ONCE(!pipe_empty(pipe->head, pipe->tail)); WARN_ON_ONCE(!pipe_empty(pipe->head, pipe->tail));
while (len) { while (len) {
unsigned int p_space;
size_t read_len; size_t read_len;
loff_t pos = sd->pos, prev_pos = pos; loff_t pos = sd->pos, prev_pos = pos;
/* Don't try to read more the pipe has space for. */ ret = do_splice_to(in, &pos, pipe, len, flags);
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);
if (unlikely(ret <= 0)) if (unlikely(ret <= 0))
goto out_release; goto out_release;
@ -1083,15 +1083,8 @@ long do_splice(struct file *in, loff_t *off_in, struct file *out,
pipe_lock(opipe); pipe_lock(opipe);
ret = wait_for_space(opipe, flags); ret = wait_for_space(opipe, flags);
if (!ret) { 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); ret = do_splice_to(in, &offset, opipe, len, flags);
}
pipe_unlock(opipe); pipe_unlock(opipe);
if (ret > 0) if (ret > 0)
wakeup_pipe_readers(opipe); wakeup_pipe_readers(opipe);