Fix the new filemap_splice_read() function to get i_size from in->f_mapping->host, not in->f_inode so that it works with block devices too (in->f_inode points to the device file, which is typically zero size). Fixes: 07073eb01c5f ("splice: Add a func to do a splice from a buffered file without ITER_PIPE") Link: https://lore.kernel.org/r/0c6b661c-f7ff-cf12-b7f0-00b6b2f1317b@xxxxxxx/ Reported-by: Ayush Jain <ayush.jain3@xxxxxxx> 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: Steve French <stfrench@xxxxxxxxxxxxx> cc: linux-mm@xxxxxxxxx cc: linux-block@xxxxxxxxxxxxxxx cc: linux-fsdevel@xxxxxxxxxxxxxxx --- mm/filemap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm/filemap.c b/mm/filemap.c index 470be06b6096..f86cc8acf33a 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2902,7 +2902,7 @@ ssize_t filemap_splice_read(struct file *in, loff_t *ppos, do { cond_resched(); - if (*ppos >= i_size_read(file_inode(in))) + if (*ppos >= i_size_read(in->f_mapping->host)) break; iocb.ki_pos = *ppos; @@ -2918,7 +2918,7 @@ ssize_t filemap_splice_read(struct file *in, loff_t *ppos, * part of the page is not copied back to userspace (unless * another truncate extends the file - this is desired though). */ - isize = i_size_read(file_inode(in)); + isize = i_size_read(in->f_mapping->host); if (unlikely(*ppos >= isize)) break; end_offset = min_t(loff_t, isize, *ppos + len);