splice: Fix buffered splice of a blockdev for-6.4/splice
authorDavid Howells <dhowells@redhat.com>
Wed, 19 Apr 2023 08:54:11 +0000 (09:54 +0100)
committerJens Axboe <axboe@kernel.dk>
Wed, 19 Apr 2023 13:10:13 +0000 (07:10 -0600)
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@amd.com/
Reported-by: Ayush Jain <ayush.jain3@amd.com>
cc: Jens Axboe <axboe@kernel.dk>
cc: Christoph Hellwig <hch@lst.de>
cc: Al Viro <viro@zeniv.linux.org.uk>
cc: David Hildenbrand <david@redhat.com>
cc: John Hubbard <jhubbard@nvidia.com>
cc: Steve French <stfrench@microsoft.com>
cc: linux-mm@kvack.org
cc: linux-block@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
Tested-by: Ayush Jain <ayush.jain3@amd.com>
Link: https://lore.kernel.org/r/1770755.1681894451@warthog.procyon.org.uk
Signed-off-by: Jens Axboe <axboe@kernel.dk>
mm/filemap.c

index 470be06b609677a1b5ad71590cea0828196421a9..f86cc8acf33a89ca71e91c994757e922bbc480c3 100644 (file)
@@ -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);