From: Joanne Koong Date: Fri, 29 Aug 2025 23:56:27 +0000 (-0700) Subject: fuse: remove fuse_readpages_end() null mapping check X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=02d47e213dce6e2fa197d0cff66e92f1bc55f00f;p=thirdparty%2Fkernel%2Fstable.git fuse: remove fuse_readpages_end() null mapping check Remove extra logic in fuse_readpages_end() that checks against null folio mappings. This was added in commit ce534fb05292 ("fuse: allow splice to move pages"): "Since the remove_from_page_cache() + add_to_page_cache_locked() are non-atomic it is possible that the page cache is repopulated in between the two and add_to_page_cache_locked() will fail. This could be fixed by creating a new atomic replace_page_cache_page() function. fuse_readpages_end() needed to be reworked so it works even if page->mapping is NULL for some or all pages which can happen if the add_to_page_cache_locked() failed." Commit ef6a3c63112e ("mm: add replace_page_cache_page() function") added atomic page cache replacement, which means the check against null mappings can be removed. Signed-off-by: Joanne Koong Signed-off-by: Miklos Szeredi --- diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 0698bcb2f9923..54786f62a9d8b 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -865,22 +865,20 @@ static void fuse_readpages_end(struct fuse_mount *fm, struct fuse_args *args, struct fuse_args_pages *ap = &ia->ap; size_t count = ia->read.in.size; size_t num_read = args->out_args[0].size; - struct address_space *mapping = NULL; - - for (i = 0; mapping == NULL && i < ap->num_folios; i++) - mapping = ap->folios[i]->mapping; + struct address_space *mapping; + struct inode *inode; - if (mapping) { - struct inode *inode = mapping->host; + WARN_ON_ONCE(!ap->num_folios); + mapping = ap->folios[0]->mapping; + inode = mapping->host; - /* - * Short read means EOF. If file size is larger, truncate it - */ - if (!err && num_read < count) - fuse_short_read(inode, ia->read.attr_ver, num_read, ap); + /* + * Short read means EOF. If file size is larger, truncate it + */ + if (!err && num_read < count) + fuse_short_read(inode, ia->read.attr_ver, num_read, ap); - fuse_invalidate_atime(inode); - } + fuse_invalidate_atime(inode); for (i = 0; i < ap->num_folios; i++) { folio_end_read(ap->folios[i], !err);