fuse: refactor out shared logic in fuse_writepages_fill() and fuse_writepage_locked()
authorJoanne Koong <joannelkoong@gmail.com>
Mon, 26 Aug 2024 21:19:08 +0000 (14:19 -0700)
committerMiklos Szeredi <mszeredi@redhat.com>
Thu, 29 Aug 2024 09:43:12 +0000 (11:43 +0200)
This change refactors the shared logic in fuse_writepages_fill() and
fuse_writepages_locked() into two separate helper functions,
fuse_writepage_args_page_fill() and fuse_writepage_args_setup().

No functional changes added.

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

index be0d7fd..fc587f3 100644 (file)
@@ -2047,49 +2047,77 @@ static void fuse_writepage_add_to_bucket(struct fuse_conn *fc,
        rcu_read_unlock();
 }
 
+static void fuse_writepage_args_page_fill(struct fuse_writepage_args *wpa, struct folio *folio,
+                                         struct folio *tmp_folio, uint32_t page_index)
+{
+       struct inode *inode = folio->mapping->host;
+       struct fuse_args_pages *ap = &wpa->ia.ap;
+
+       folio_copy(tmp_folio, folio);
+
+       ap->pages[page_index] = &tmp_folio->page;
+       ap->descs[page_index].offset = 0;
+       ap->descs[page_index].length = PAGE_SIZE;
+
+       inc_wb_stat(&inode_to_bdi(inode)->wb, WB_WRITEBACK);
+       inc_node_page_state(&tmp_folio->page, NR_WRITEBACK_TEMP);
+}
+
+static struct fuse_writepage_args *fuse_writepage_args_setup(struct folio *folio,
+                                                            struct fuse_file *ff)
+{
+       struct inode *inode = folio->mapping->host;
+       struct fuse_conn *fc = get_fuse_conn(inode);
+       struct fuse_writepage_args *wpa;
+       struct fuse_args_pages *ap;
+
+       wpa = fuse_writepage_args_alloc();
+       if (!wpa)
+               return NULL;
+
+       fuse_writepage_add_to_bucket(fc, wpa);
+       fuse_write_args_fill(&wpa->ia, ff, folio_pos(folio), 0);
+       wpa->ia.write.in.write_flags |= FUSE_WRITE_CACHE;
+       wpa->inode = inode;
+       wpa->ia.ff = ff;
+
+       ap = &wpa->ia.ap;
+       ap->args.in_pages = true;
+       ap->args.end = fuse_writepage_end;
+
+       return wpa;
+}
+
 static int fuse_writepage_locked(struct folio *folio)
 {
        struct address_space *mapping = folio->mapping;
        struct inode *inode = mapping->host;
-       struct fuse_conn *fc = get_fuse_conn(inode);
        struct fuse_inode *fi = get_fuse_inode(inode);
        struct fuse_writepage_args *wpa;
        struct fuse_args_pages *ap;
        struct folio *tmp_folio;
+       struct fuse_file *ff;
        int error = -ENOMEM;
 
-       folio_start_writeback(folio);
-
-       wpa = fuse_writepage_args_alloc();
-       if (!wpa)
-               goto err;
-       ap = &wpa->ia.ap;
-
        tmp_folio = folio_alloc(GFP_NOFS | __GFP_HIGHMEM, 0);
        if (!tmp_folio)
-               goto err_free;
+               goto err;
 
        error = -EIO;
-       wpa->ia.ff = fuse_write_file_get(fi);
-       if (!wpa->ia.ff)
+       ff = fuse_write_file_get(fi);
+       if (!ff)
                goto err_nofile;
 
-       fuse_writepage_add_to_bucket(fc, wpa);
-       fuse_write_args_fill(&wpa->ia, wpa->ia.ff, folio_pos(folio), 0);
+       wpa = fuse_writepage_args_setup(folio, ff);
+       error = -ENOMEM;
+       if (!wpa)
+               goto err_writepage_args;
 
-       folio_copy(tmp_folio, folio);
-       wpa->ia.write.in.write_flags |= FUSE_WRITE_CACHE;
-       wpa->next = NULL;
-       ap->args.in_pages = true;
+       ap = &wpa->ia.ap;
        ap->num_pages = 1;
-       ap->pages[0] = &tmp_folio->page;
-       ap->descs[0].offset = 0;
-       ap->descs[0].length = PAGE_SIZE;
-       ap->args.end = fuse_writepage_end;
-       wpa->inode = inode;
 
-       inc_wb_stat(&inode_to_bdi(inode)->wb, WB_WRITEBACK);
-       node_stat_add_folio(tmp_folio, NR_WRITEBACK_TEMP);
+       folio_start_writeback(folio);
+       fuse_writepage_args_page_fill(wpa, folio, tmp_folio, 0);
 
        spin_lock(&fi->lock);
        tree_insert(&fi->writepages, wpa);
@@ -2101,13 +2129,12 @@ static int fuse_writepage_locked(struct folio *folio)
 
        return 0;
 
+err_writepage_args:
+       fuse_file_put(ff, false);
 err_nofile:
        folio_put(tmp_folio);
-err_free:
-       kfree(wpa);
 err:
        mapping_set_error(folio->mapping, error);
-       folio_end_writeback(folio);
        return error;
 }
 
@@ -2285,36 +2312,20 @@ static int fuse_writepages_fill(struct folio *folio,
         */
        if (data->wpa == NULL) {
                err = -ENOMEM;
-               wpa = fuse_writepage_args_alloc();
+               wpa = fuse_writepage_args_setup(folio, data->ff);
                if (!wpa) {
                        folio_put(tmp_folio);
                        goto out_unlock;
                }
-               fuse_writepage_add_to_bucket(fc, wpa);
-
+               fuse_file_get(wpa->ia.ff);
                data->max_pages = 1;
-
                ap = &wpa->ia.ap;
-               fuse_write_args_fill(&wpa->ia, data->ff, folio_pos(folio), 0);
-               wpa->ia.write.in.write_flags |= FUSE_WRITE_CACHE;
-               wpa->ia.ff = fuse_file_get(data->ff);
-               wpa->next = NULL;
-               ap->args.in_pages = true;
-               ap->args.end = fuse_writepage_end;
-               ap->num_pages = 0;
-               wpa->inode = inode;
        }
        folio_start_writeback(folio);
 
-       folio_copy(tmp_folio, folio);
-       ap->pages[ap->num_pages] = &tmp_folio->page;
-       ap->descs[ap->num_pages].offset = 0;
-       ap->descs[ap->num_pages].length = PAGE_SIZE;
+       fuse_writepage_args_page_fill(wpa, folio, tmp_folio, ap->num_pages);
        data->orig_pages[ap->num_pages] = &folio->page;
 
-       inc_wb_stat(&inode_to_bdi(inode)->wb, WB_WRITEBACK);
-       inc_node_page_state(&tmp_folio->page, NR_WRITEBACK_TEMP);
-
        err = 0;
        if (data->wpa) {
                /*