From b8ada80b9d6909c2fdb43f05cdd0ac3133ea776d Mon Sep 17 00:00:00 2001 From: Tal Zussman Date: Thu, 24 Sep 2026 19:42:16 -0400 Subject: [PATCH] fuse: convert fuse_add_dirent_to_cache() to use folios Replace find_lock_page() and find_or_create_page() with filemap_lock_folio() and filemap_grab_folio(), and switch the remaining page helpers to their folio equivalents. Each index of the readdir cache holds one page of dirents. fuse does not enable large folios, so these folios are always a single page. Also write the dirent with folio_fill_tail() and memcpy_to_folio() instead of open-coding it. This removes two hidden calls to compound_head() and one of the last callers of find_lock_page(). Signed-off-by: Tal Zussman Signed-off-by: Miklos Szeredi --- fs/fuse/readdir.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/fs/fuse/readdir.c b/fs/fuse/readdir.c index 5ca87151d70d..e6b828eb41a5 100644 --- a/fs/fuse/readdir.c +++ b/fs/fuse/readdir.c @@ -34,11 +34,11 @@ static void fuse_add_dirent_to_cache(struct file *file, struct fuse_inode *fi = get_fuse_inode(file_inode(file)); size_t reclen = FUSE_DIRENT_SIZE(dirent); pgoff_t index; - struct page *page; + struct folio *folio; loff_t size; u64 version; unsigned int offset; - void *addr; + size_t folio_offset; /* Dirent doesn't fit in readdir cache page? Skip caching. */ if (reclen > PAGE_SIZE) @@ -64,13 +64,11 @@ static void fuse_add_dirent_to_cache(struct file *file, } spin_unlock(&fi->rdc.lock); - if (offset) { - page = find_lock_page(file->f_mapping, index); - } else { - page = find_or_create_page(file->f_mapping, index, - mapping_gfp_mask(file->f_mapping)); - } - if (!page) + if (offset) + folio = filemap_lock_folio(file->f_mapping, index); + else + folio = filemap_grab_folio(file->f_mapping, index); + if (IS_ERR(folio)) return; spin_lock(&fi->rdc.lock); @@ -79,19 +77,21 @@ static void fuse_add_dirent_to_cache(struct file *file, WARN_ON(fi->rdc.pos != pos)) goto unlock; - addr = kmap_local_page(page); + folio_offset = offset_in_folio(folio, (index << PAGE_SHIFT) + offset); if (!offset) { - clear_page(addr); - SetPageUptodate(page); + folio_fill_tail(folio, folio_offset, (const char *)dirent, + reclen); + folio_mark_uptodate(folio); + } else { + memcpy_to_folio(folio, folio_offset, (const char *)dirent, + reclen); } - memcpy(addr + offset, dirent, reclen); - kunmap_local(addr); fi->rdc.size = (index << PAGE_SHIFT) + offset + reclen; fi->rdc.pos = dirent->off; unlock: spin_unlock(&fi->rdc.lock); - unlock_page(page); - put_page(page); + folio_unlock(folio); + folio_put(folio); } static void fuse_readdir_cache_end(struct file *file, loff_t pos)