Make generic_file_splice_read() use filemap_splice_read() and
direct_splice_read() rather than using an ITER_PIPE and call_read_iter().
With this, ITER_PIPE is no longer used.
Signed-off-by: David Howells <
dhowells@xxxxxxxxxx>
cc: Jens Axboe <
axboe@xxxxxxxxx>
cc: Christoph Hellwig <
hch@xxxxxx>
cc: Al Viro <
viro@xxxxxxxxxxxxxxxxxx>
cc: David Hildenbrand <
david@xxxxxxxxxx>
cc: John Hubbard <
jhubbard@xxxxxxxxxx>
cc:
linux-mm@xxxxxxxxxcc:
linux-block@xxxxxxxxxxxxxxxcc:
linux-fsdevel@xxxxxxxxxxxxxxx---
Notes:
ver #14)
- Split out filemap_splice_read() into a separate patch.
fs/splice.c | 30 +++++++-----------------------
1 file changed, 7 insertions(+), 23 deletions(-)
diff --git a/fs/splice.c b/fs/splice.c
index 4c6332854b63..a93478338cec 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -391,29 +391,13 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
struct pipe_inode_info *pipe, size_t len,
unsigned int flags)
{
-
struct iov_iter to;
-
struct kiocb kiocb;
-
int ret;
-
-
iov_iter_pipe(&to, ITER_DEST, pipe, len);
-
init_sync_kiocb(&kiocb, in);
-
kiocb.ki_pos = *ppos;
-
ret = call_read_iter(in, &kiocb, &to);
-
if (ret > 0) {
-
*ppos = kiocb.ki_pos;
-
file_accessed(in);
-
} else if (ret < 0) {
-
/* free what was emitted */
-
pipe_discard_from(pipe, to.start_head);
-
/*
-
* callers of ->splice_read() expect -EAGAIN on
-
* "can't put anything in there", rather than -EFAULT.
-
*/
-
if (ret == -EFAULT)
-
ret = -EAGAIN;
-
}
-
-
return ret;
+
if (unlikely(*ppos >= file_inode(in)->i_sb->s_maxbytes))
+
return 0;
+
if (unlikely(!len))
+
return 0;
+
if (in->f_flags & O_DIRECT)
+
return direct_splice_read(in, ppos, pipe, len, flags);
+
return filemap_splice_read(in, ppos, pipe, len, flags);
}
EXPORT_SYMBOL(generic_file_splice_read);