diff options
author | David Howells <dhowells@redhat.com> | 2023-05-22 16:49:54 +0300 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2023-05-24 17:42:16 +0300 |
commit | aa3dbde878961dd333cdd3c326b93e6c84a23ed4 (patch) | |
tree | 960bbf6eda7f857001501ee6c909bb0d2dc60029 | |
parent | 123856f0e83f457a3a24d15f561a1dd5f0d4b482 (diff) | |
download | linux-aa3dbde878961dd333cdd3c326b93e6c84a23ed4.tar.xz |
splice: Make splice from an O_DIRECT fd use copy_splice_read()
Make a read splice from a file descriptor that's open O_DIRECT use
copy_splice_read() to do the reading as filemap_splice_read() is unlikely
to find any pagecache to splice.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Christian Brauner <brauner@kernel.org>
cc: Al Viro <viro@zeniv.linux.org.uk>
cc: Jens Axboe <axboe@kernel.dk>
cc: linux-fsdevel@vger.kernel.org
cc: linux-block@vger.kernel.org
cc: linux-mm@kvack.org
Link: https://lore.kernel.org/r/20230522135018.2742245-8-dhowells@redhat.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | fs/splice.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/fs/splice.c b/fs/splice.c index fe3309ffeb26..76126b1aafcb 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -907,6 +907,12 @@ long vfs_splice_read(struct file *in, loff_t *ppos, if (unlikely(!in->f_op->splice_read)) return warn_unsupported(in, "read"); + /* + * O_DIRECT doesn't deal with the pagecache, so we allocate a buffer, + * copy into it and splice that into the pipe. + */ + if ((in->f_flags & O_DIRECT)) + return copy_splice_read(in, ppos, pipe, len, flags); return in->f_op->splice_read(in, ppos, pipe, len, flags); } EXPORT_SYMBOL_GPL(vfs_splice_read); |