Make direct_read_splice() limit the read to the end of the file for regular files and block devices, thereby reducing the amount of allocation it will do in such a case. This means that the blockdev code doesn't require any special handling as filemap_read_splice() also limits to i_size. Signed-off-by: David Howells <dhowells@xxxxxxxxxx> cc: Christoph Hellwig <hch@xxxxxx> cc: Al Viro <viro@xxxxxxxxxxxxxxxxxx> cc: Jens Axboe <axboe@xxxxxxxxx> cc: linux-block@xxxxxxxxxxxxxxx cc: linux-fsdevel@xxxxxxxxxxxxxxx cc: linux-mm@xxxxxxxxx --- fs/splice.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/fs/splice.c b/fs/splice.c index 4db3eee49423..89c8516554d1 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -315,6 +315,19 @@ ssize_t direct_splice_read(struct file *in, loff_t *ppos, size_t used, npages, chunk, remain, keep = 0; int i; + if (!len) + return 0; + + if (S_ISREG(file_inode(in)->i_mode) || + S_ISBLK(file_inode(in)->i_mode)) { + loff_t i_size = i_size_read(in->f_mapping->host); + + if (*ppos >= i_size) + return 0; + if (len > i_size - *ppos) + len = i_size - *ppos; + } + /* Work out how much data we can actually add into the pipe */ used = pipe_occupancy(pipe->head, pipe->tail); npages = max_t(ssize_t, pipe->max_usage - used, 0);