Skip to content

Commit 326ba91

Browse files
djwonggregkh
authored andcommitted
splice: only read in as much information as there is pipe buffer space
commit 3253d9d upstream. Andreas Grünbacher reports that on the two filesystems that support iomap directio, it's possible for splice() to return -EAGAIN (instead of a short splice) if the pipe being written to has less space available in its pipe buffers than the length supplied by the calling process. Months ago we fixed splice_direct_to_actor to clamp the length of the read request to the size of the splice pipe. Do the same to do_splice. Fixes: 1761444 ("splice: don't read more than available pipe space") Reported-by: [email protected] Reported-by: Andreas Grünbacher <[email protected]> Reviewed-by: Andreas Grünbacher <[email protected]> Signed-off-by: Darrick J. Wong <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 42a929e commit 326ba91

File tree

1 file changed

+11
-3
lines changed

1 file changed

+11
-3
lines changed

fs/splice.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -949,12 +949,13 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
949949
WARN_ON_ONCE(pipe->nrbufs != 0);
950950

951951
while (len) {
952+
unsigned int pipe_pages;
952953
size_t read_len;
953954
loff_t pos = sd->pos, prev_pos = pos;
954955

955956
/* Don't try to read more the pipe has space for. */
956-
read_len = min_t(size_t, len,
957-
(pipe->buffers - pipe->nrbufs) << PAGE_SHIFT);
957+
pipe_pages = pipe->buffers - pipe->nrbufs;
958+
read_len = min(len, (size_t)pipe_pages << PAGE_SHIFT);
958959
ret = do_splice_to(in, &pos, pipe, read_len, flags);
959960
if (unlikely(ret <= 0))
960961
goto out_release;
@@ -1175,8 +1176,15 @@ static long do_splice(struct file *in, loff_t __user *off_in,
11751176

11761177
pipe_lock(opipe);
11771178
ret = wait_for_space(opipe, flags);
1178-
if (!ret)
1179+
if (!ret) {
1180+
unsigned int pipe_pages;
1181+
1182+
/* Don't try to read more the pipe has space for. */
1183+
pipe_pages = opipe->buffers - opipe->nrbufs;
1184+
len = min(len, (size_t)pipe_pages << PAGE_SHIFT);
1185+
11791186
ret = do_splice_to(in, &offset, opipe, len, flags);
1187+
}
11801188
pipe_unlock(opipe);
11811189
if (ret > 0)
11821190
wakeup_pipe_readers(opipe);

0 commit comments

Comments
 (0)