]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
fuse: Convert fuse_write_begin() to use a folio
authorMatthew Wilcox (Oracle) <willy@infradead.org>
Thu, 11 Jul 2024 20:58:06 +0000 (16:58 -0400)
committerChristian Brauner <brauner@kernel.org>
Wed, 7 Aug 2024 09:32:01 +0000 (11:32 +0200)
Fetch a folio from the page cache instead of a page and use it throughout
removing several calls to compound_head() and supporting large folios
(in this function).  We still have to convert back to a page for calling
internal fuse functions, but hopefully they will be converted soon.

Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/fuse/file.c

index f4102c6657af7dea65a6be975a126a95d03fc516..137485999d3d1b0277a9e692cfcceda908955ecf 100644 (file)
@@ -2391,41 +2391,42 @@ static int fuse_write_begin(struct file *file, struct address_space *mapping,
 {
        pgoff_t index = pos >> PAGE_SHIFT;
        struct fuse_conn *fc = get_fuse_conn(file_inode(file));
-       struct page *page;
+       struct folio *folio;
        loff_t fsize;
        int err = -ENOMEM;
 
        WARN_ON(!fc->writeback_cache);
 
-       page = grab_cache_page_write_begin(mapping, index);
-       if (!page)
+       folio = __filemap_get_folio(mapping, index, FGP_WRITEBEGIN,
+                       mapping_gfp_mask(mapping));
+       if (IS_ERR(folio))
                goto error;
 
-       fuse_wait_on_page_writeback(mapping->host, page->index);
+       fuse_wait_on_page_writeback(mapping->host, folio->index);
 
-       if (PageUptodate(page) || len == PAGE_SIZE)
+       if (folio_test_uptodate(folio) || len >= folio_size(folio))
                goto success;
        /*
-        * Check if the start this page comes after the end of file, in which
-        * case the readpage can be optimized away.
+        * Check if the start of this folio comes after the end of file,
+        * in which case the readpage can be optimized away.
         */
        fsize = i_size_read(mapping->host);
-       if (fsize <= (pos & PAGE_MASK)) {
-               size_t off = pos & ~PAGE_MASK;
+       if (fsize <= folio_pos(folio)) {
+               size_t off = offset_in_folio(folio, pos);
                if (off)
-                       zero_user_segment(page, 0, off);
+                       folio_zero_segment(folio, 0, off);
                goto success;
        }
-       err = fuse_do_readpage(file, page);
+       err = fuse_do_readpage(file, &folio->page);
        if (err)
                goto cleanup;
 success:
-       *pagep = page;
+       *pagep = &folio->page;
        return 0;
 
 cleanup:
-       unlock_page(page);
-       put_page(page);
+       folio_unlock(folio);
+       folio_put(folio);
 error:
        return err;
 }