]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
fuse: support large folios for writeback
authorJoanne Koong <joannelkoong@gmail.com>
Mon, 12 May 2025 22:58:40 +0000 (15:58 -0700)
committerMiklos Szeredi <mszeredi@redhat.com>
Thu, 29 May 2025 10:31:23 +0000 (12:31 +0200)
Add support for folios larger than one page size for writeback.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/fuse/file.c

index 07ff81469a59346a4549c4c59b8e2b44a8b163f6..3d0b33be3824ad0d3cab4ecf85d48614cf957798 100644 (file)
@@ -1988,7 +1988,7 @@ static void fuse_writepage_args_page_fill(struct fuse_writepage_args *wpa, struc
 
        ap->folios[folio_index] = folio;
        ap->descs[folio_index].offset = 0;
-       ap->descs[folio_index].length = PAGE_SIZE;
+       ap->descs[folio_index].length = folio_size(folio);
 
        inc_wb_stat(&inode_to_bdi(inode)->wb, WB_WRITEBACK);
 }
@@ -2062,6 +2062,7 @@ struct fuse_fill_wb_data {
        struct fuse_file *ff;
        struct inode *inode;
        unsigned int max_folios;
+       unsigned int nr_pages;
 };
 
 static bool fuse_pages_realloc(struct fuse_fill_wb_data *data)
@@ -2109,15 +2110,15 @@ static bool fuse_writepage_need_send(struct fuse_conn *fc, struct folio *folio,
        WARN_ON(!ap->num_folios);
 
        /* Reached max pages */
-       if (ap->num_folios == fc->max_pages)
+       if (data->nr_pages + folio_nr_pages(folio) > fc->max_pages)
                return true;
 
        /* Reached max write bytes */
-       if ((ap->num_folios + 1) * PAGE_SIZE > fc->max_write)
+       if ((data->nr_pages * PAGE_SIZE) + folio_size(folio) > fc->max_write)
                return true;
 
        /* Discontinuity */
-       if (ap->folios[ap->num_folios - 1]->index + 1 != folio_index(folio))
+       if (folio_next_index(ap->folios[ap->num_folios - 1]) != folio_index(folio))
                return true;
 
        /* Need to grow the pages array?  If so, did the expansion fail? */
@@ -2148,6 +2149,7 @@ static int fuse_writepages_fill(struct folio *folio,
        if (wpa && fuse_writepage_need_send(fc, folio, ap, data)) {
                fuse_writepages_send(data);
                data->wpa = NULL;
+               data->nr_pages = 0;
        }
 
        if (data->wpa == NULL) {
@@ -2162,6 +2164,7 @@ static int fuse_writepages_fill(struct folio *folio,
        folio_start_writeback(folio);
 
        fuse_writepage_args_page_fill(wpa, folio, ap->num_folios);
+       data->nr_pages += folio_nr_pages(folio);
 
        err = 0;
        ap->num_folios++;
@@ -2192,6 +2195,7 @@ static int fuse_writepages(struct address_space *mapping,
        data.inode = inode;
        data.wpa = NULL;
        data.ff = NULL;
+       data.nr_pages = 0;
 
        err = write_cache_pages(mapping, wbc, fuse_writepages_fill, &data);
        if (data.wpa) {