[PATCH v2] fuse: honor desc offset in readahead reads

Haofeng Li <[email protected]> Fri, 17 Jul 2026 11:28:35 +0800
Newsgroups dev.linux.lists.fuse-devel,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
fuse_handle_readahead records non-zero descs[].offset when
iomap skips leading uptodate blocks in a folio, but
fuse_send_readpages built FUSE_READ from folio_pos() alone.
The reply was still copied at descs[0].offset, so wrong
file data was placed into the page cache.

Add descs[0].offset to the request position. Apply the
same correction in fuse_short_read for EOF size updates.

Fixes: 4ea907108a5c ("fuse: use iomap for readahead")
Signed-off-by: Haofeng Li <[email protected]>
Reviewed-by: Joanne Koong <[email protected]>

---
Changes in v2:
- Collapse the split line in fuse_send_readpages back into one line.
- Add Joanne's Reviewed-by tag.
---
 fs/fuse/file.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index ceada75310b8..9718a0353d26 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -836,7 +836,8 @@ static void fuse_short_read(struct inode *inode, u64 attr_ver, size_t num_read,
 	 * reached the client fs yet.  So the hole is not present there.
 	 */
 	if (!fc->writeback_cache) {
-		loff_t pos = folio_pos(ap->folios[0]) + num_read;
+		loff_t pos = folio_pos(ap->folios[0]) +
+			     ap->descs[0].offset + num_read;
 		fuse_read_update_size(inode, pos, attr_ver);
 	}
 }
@@ -1057,7 +1058,7 @@ static void fuse_send_readpages(struct fuse_io_args *ia, struct file *file,
 	struct fuse_file *ff = file->private_data;
 	struct fuse_mount *fm = ff->fm;
 	struct fuse_args_pages *ap = &ia->ap;
-	loff_t pos = folio_pos(ap->folios[0]);
+	loff_t pos = folio_pos(ap->folios[0]) + ap->descs[0].offset;
 	ssize_t res;
 	int err;
 
-- 
2.25.1