fuse: remove pages for requests and exclusively use folios
authorJoanne Koong <joannelkoong@gmail.com>
Thu, 24 Oct 2024 17:18:09 +0000 (10:18 -0700)
committerMiklos Szeredi <mszeredi@redhat.com>
Tue, 5 Nov 2024 13:08:35 +0000 (14:08 +0100)
All fuse requests use folios instead of pages for transferring data.
Remove pages from the requests and exclusively use folios.

No functional changes.

[SzM: rename back folio_descs -> descs, etc.]

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/cuse.c
fs/fuse/dev.c
fs/fuse/dir.c
fs/fuse/file.c
fs/fuse/fuse_i.h
fs/fuse/ioctl.c
fs/fuse/readdir.c
fs/fuse/virtio_fs.c

index eed78e3..b39844d 100644 (file)
@@ -460,10 +460,9 @@ static int cuse_send_init(struct cuse_conn *cc)
        ap->args.out_args[1].size = CUSE_INIT_INFO_MAX;
        ap->args.out_argvar = true;
        ap->args.out_pages = true;
-       ap->uses_folios = true;
        ap->num_folios = 1;
        ap->folios = &ia->folio;
-       ap->folio_descs = &ia->desc;
+       ap->descs = &ia->desc;
        ia->folio = folio;
        ia->desc.length = ap->args.out_args[1].size;
        ap->args.end = cuse_process_init_reply;
index 563a0bf..29fc61a 100644 (file)
@@ -1028,41 +1028,27 @@ static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes,
        struct fuse_req *req = cs->req;
        struct fuse_args_pages *ap = container_of(req->args, typeof(*ap), args);
 
-       if (ap->uses_folios) {
-               for (i = 0; i < ap->num_folios && (nbytes || zeroing); i++) {
-                       int err;
-                       unsigned int offset = ap->folio_descs[i].offset;
-                       unsigned int count = min(nbytes, ap->folio_descs[i].length);
-                       struct page *orig, *pagep;
+       for (i = 0; i < ap->num_folios && (nbytes || zeroing); i++) {
+               int err;
+               unsigned int offset = ap->descs[i].offset;
+               unsigned int count = min(nbytes, ap->descs[i].length);
+               struct page *orig, *pagep;
 
-                       orig = pagep = &ap->folios[i]->page;
+               orig = pagep = &ap->folios[i]->page;
 
-                       err = fuse_copy_page(cs, &pagep, offset, count, zeroing);
-                       if (err)
-                               return err;
-
-                       nbytes -= count;
-
-                       /*
-                        *  fuse_copy_page may have moved a page from a pipe
-                        *  instead of copying into our given page, so update
-                        *  the folios if it was replaced.
-                        */
-                       if (pagep != orig)
-                               ap->folios[i] = page_folio(pagep);
-               }
-       } else {
-               for (i = 0; i < ap->num_pages && (nbytes || zeroing); i++) {
-                       int err;
-                       unsigned int offset = ap->descs[i].offset;
-                       unsigned int count = min(nbytes, ap->descs[i].length);
+               err = fuse_copy_page(cs, &pagep, offset, count, zeroing);
+               if (err)
+                       return err;
 
-                       err = fuse_copy_page(cs, &ap->pages[i], offset, count, zeroing);
-                       if (err)
-                               return err;
+               nbytes -= count;
 
-                       nbytes -= count;
-               }
+               /*
+                *  fuse_copy_page may have moved a page from a pipe instead of
+                *  copying into our given page, so update the folios if it was
+                *  replaced.
+                */
+               if (pagep != orig)
+                       ap->folios[i] = page_folio(pagep);
        }
        return 0;
 }
@@ -1761,7 +1747,7 @@ static int fuse_retrieve(struct fuse_mount *fm, struct inode *inode,
        num_pages = (num + offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
        num_pages = min(num_pages, fc->max_pages);
 
-       args_size += num_pages * (sizeof(ap->folios[0]) + sizeof(ap->folio_descs[0]));
+       args_size += num_pages * (sizeof(ap->folios[0]) + sizeof(ap->descs[0]));
 
        ra = kzalloc(args_size, GFP_KERNEL);
        if (!ra)
@@ -1769,8 +1755,7 @@ static int fuse_retrieve(struct fuse_mount *fm, struct inode *inode,
 
        ap = &ra->ap;
        ap->folios = (void *) (ra + 1);
-       ap->folio_descs = (void *) (ap->folios + num_pages);
-       ap->uses_folios = true;
+       ap->descs = (void *) (ap->folios + num_pages);
 
        args = &ap->args;
        args->nodeid = outarg->nodeid;
@@ -1791,8 +1776,8 @@ static int fuse_retrieve(struct fuse_mount *fm, struct inode *inode,
 
                this_num = min_t(unsigned, num, PAGE_SIZE - offset);
                ap->folios[ap->num_folios] = folio;
-               ap->folio_descs[ap->num_folios].offset = offset;
-               ap->folio_descs[ap->num_folios].length = this_num;
+               ap->descs[ap->num_folios].offset = offset;
+               ap->descs[ap->num_folios].length = this_num;
                ap->num_folios++;
                cur_pages++;
 
index a08c532..b8a4608 100644 (file)
@@ -1590,10 +1590,9 @@ static int fuse_readlink_page(struct inode *inode, struct folio *folio)
        struct fuse_mount *fm = get_fuse_mount(inode);
        struct fuse_folio_desc desc = { .length = PAGE_SIZE - 1 };
        struct fuse_args_pages ap = {
-               .uses_folios = true,
                .num_folios = 1,
                .folios = &folio,
-               .folio_descs = &desc,
+               .descs = &desc,
        };
        char *link;
        ssize_t res;
index 14af8c4..88d0946 100644 (file)
@@ -742,7 +742,7 @@ static void fuse_aio_complete(struct fuse_io_priv *io, int err, ssize_t pos)
        kref_put(&io->refcnt, fuse_io_release);
 }
 
-static struct fuse_io_args *fuse_io_folios_alloc(struct fuse_io_priv *io,
+static struct fuse_io_args *fuse_io_alloc(struct fuse_io_priv *io,
                                                 unsigned int nfolios)
 {
        struct fuse_io_args *ia;
@@ -750,9 +750,8 @@ static struct fuse_io_args *fuse_io_folios_alloc(struct fuse_io_priv *io,
        ia = kzalloc(sizeof(*ia), GFP_KERNEL);
        if (ia) {
                ia->io = io;
-               ia->ap.uses_folios = true;
                ia->ap.folios = fuse_folios_alloc(nfolios, GFP_KERNEL,
-                                                 &ia->ap.folio_descs);
+                                                 &ia->ap.descs);
                if (!ia->ap.folios) {
                        kfree(ia);
                        ia = NULL;
@@ -761,7 +760,7 @@ static struct fuse_io_args *fuse_io_folios_alloc(struct fuse_io_priv *io,
        return ia;
 }
 
-static void fuse_io_folios_free(struct fuse_io_args *ia)
+static void fuse_io_free(struct fuse_io_args *ia)
 {
        kfree(ia->ap.folios);
        kfree(ia);
@@ -797,7 +796,7 @@ static void fuse_aio_complete_req(struct fuse_mount *fm, struct fuse_args *args,
        fuse_release_user_pages(&ia->ap, err ?: nres, io->should_dirty);
 
        fuse_aio_complete(io, err, pos);
-       fuse_io_folios_free(ia);
+       fuse_io_free(ia);
 }
 
 static ssize_t fuse_async_req_send(struct fuse_mount *fm,
@@ -880,10 +879,9 @@ static int fuse_do_readfolio(struct file *file, struct folio *folio)
        struct fuse_io_args ia = {
                .ap.args.page_zeroing = true,
                .ap.args.out_pages = true,
-               .ap.uses_folios = true,
                .ap.num_folios = 1,
                .ap.folios = &folio,
-               .ap.folio_descs = &desc,
+               .ap.descs = &desc,
        };
        ssize_t res;
        u64 attr_ver;
@@ -962,7 +960,7 @@ static void fuse_readpages_end(struct fuse_mount *fm, struct fuse_args *args,
        if (ia->ff)
                fuse_file_put(ia->ff, false);
 
-       fuse_io_folios_free(ia);
+       fuse_io_free(ia);
 }
 
 static void fuse_send_readpages(struct fuse_io_args *ia, struct file *file)
@@ -983,7 +981,7 @@ static void fuse_send_readpages(struct fuse_io_args *ia, struct file *file)
        /* Don't overflow end offset */
        if (pos + (count - 1) == LLONG_MAX) {
                count--;
-               ap->folio_descs[ap->num_folios - 1].length--;
+               ap->descs[ap->num_folios - 1].length--;
        }
        WARN_ON((loff_t) (pos + count) < 0);
 
@@ -1044,7 +1042,7 @@ static void fuse_readahead(struct readahead_control *rac)
                         */
                        break;
 
-               ia = fuse_io_folios_alloc(NULL, cur_pages);
+               ia = fuse_io_alloc(NULL, cur_pages);
                if (!ia)
                        return;
                ap = &ia->ap;
@@ -1052,7 +1050,7 @@ static void fuse_readahead(struct readahead_control *rac)
                while (ap->num_folios < cur_pages) {
                        folio = readahead_folio(rac);
                        ap->folios[ap->num_folios] = folio;
-                       ap->folio_descs[ap->num_folios].length = folio_size(folio);
+                       ap->descs[ap->num_folios].length = folio_size(folio);
                        ap->num_folios++;
                }
                fuse_send_readpages(ia, rac->file);
@@ -1186,7 +1184,7 @@ static ssize_t fuse_send_write_pages(struct fuse_io_args *ia,
                err = -EIO;
 
        short_write = ia->write.out.size < count;
-       offset = ap->folio_descs[0].offset;
+       offset = ap->descs[0].offset;
        count = ia->write.out.size;
        for (i = 0; i < ap->num_folios; i++) {
                struct folio *folio = ap->folios[i];
@@ -1224,7 +1222,7 @@ static ssize_t fuse_fill_write_pages(struct fuse_io_args *ia,
        int err;
 
        ap->args.in_pages = true;
-       ap->folio_descs[0].offset = offset;
+       ap->descs[0].offset = offset;
 
        do {
                size_t tmp;
@@ -1261,7 +1259,7 @@ static ssize_t fuse_fill_write_pages(struct fuse_io_args *ia,
 
                err = 0;
                ap->folios[ap->num_folios] = folio;
-               ap->folio_descs[ap->num_folios].length = tmp;
+               ap->descs[ap->num_folios].length = tmp;
                ap->num_folios++;
                nr_pages++;
 
@@ -1318,8 +1316,7 @@ static ssize_t fuse_perform_write(struct kiocb *iocb, struct iov_iter *ii)
                unsigned int nr_pages = fuse_wr_pages(pos, iov_iter_count(ii),
                                                      fc->max_pages);
 
-               ap->uses_folios = true;
-               ap->folios = fuse_folios_alloc(nr_pages, GFP_KERNEL, &ap->folio_descs);
+               ap->folios = fuse_folios_alloc(nr_pages, GFP_KERNEL, &ap->descs);
                if (!ap->folios) {
                        err = -ENOMEM;
                        break;
@@ -1564,13 +1561,13 @@ static int fuse_get_user_pages(struct fuse_args_pages *ap, struct iov_iter *ii,
                /* Currently, all folios in FUSE are one page */
                nfolios = DIV_ROUND_UP(ret, PAGE_SIZE);
 
-               ap->folio_descs[ap->num_folios].offset = start;
-               fuse_folio_descs_length_init(ap->folio_descs, ap->num_folios, nfolios);
+               ap->descs[ap->num_folios].offset = start;
+               fuse_folio_descs_length_init(ap->descs, ap->num_folios, nfolios);
                for (i = 0; i < nfolios; i++)
                        ap->folios[i + ap->num_folios] = page_folio(pages[i]);
 
                ap->num_folios += nfolios;
-               ap->folio_descs[ap->num_folios - 1].length -=
+               ap->descs[ap->num_folios - 1].length -=
                        (PAGE_SIZE - ret) & (PAGE_SIZE - 1);
                nr_pages += nfolios;
        }
@@ -1614,14 +1611,14 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
        bool fopen_direct_io = ff->open_flags & FOPEN_DIRECT_IO;
 
        max_pages = iov_iter_npages(iter, fc->max_pages);
-       ia = fuse_io_folios_alloc(io, max_pages);
+       ia = fuse_io_alloc(io, max_pages);
        if (!ia)
                return -ENOMEM;
 
        if (fopen_direct_io && fc->direct_io_allow_mmap) {
                res = filemap_write_and_wait_range(mapping, pos, pos + count - 1);
                if (res) {
-                       fuse_io_folios_free(ia);
+                       fuse_io_free(ia);
                        return res;
                }
        }
@@ -1636,7 +1633,7 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
        if (fopen_direct_io && write) {
                res = invalidate_inode_pages2_range(mapping, idx_from, idx_to);
                if (res) {
-                       fuse_io_folios_free(ia);
+                       fuse_io_free(ia);
                        return res;
                }
        }
@@ -1663,7 +1660,7 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
 
                if (!io->async || nres < 0) {
                        fuse_release_user_pages(&ia->ap, nres, io->should_dirty);
-                       fuse_io_folios_free(ia);
+                       fuse_io_free(ia);
                }
                ia = NULL;
                if (nres < 0) {
@@ -1682,13 +1679,13 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
                }
                if (count) {
                        max_pages = iov_iter_npages(iter, fc->max_pages);
-                       ia = fuse_io_folios_alloc(io, max_pages);
+                       ia = fuse_io_alloc(io, max_pages);
                        if (!ia)
                                break;
                }
        }
        if (ia)
-               fuse_io_folios_free(ia);
+               fuse_io_free(ia);
        if (res > 0)
                *ppos = pos;
 
@@ -2093,8 +2090,7 @@ static struct fuse_writepage_args *fuse_writepage_args_alloc(void)
        if (wpa) {
                ap = &wpa->ia.ap;
                ap->num_folios = 0;
-               ap->uses_folios = true;
-               ap->folios = fuse_folios_alloc(1, GFP_NOFS, &ap->folio_descs);
+               ap->folios = fuse_folios_alloc(1, GFP_NOFS, &ap->descs);
                if (!ap->folios) {
                        kfree(wpa);
                        wpa = NULL;
@@ -2127,8 +2123,8 @@ static void fuse_writepage_args_page_fill(struct fuse_writepage_args *wpa, struc
        folio_copy(tmp_folio, folio);
 
        ap->folios[folio_index] = tmp_folio;
-       ap->folio_descs[folio_index].offset = 0;
-       ap->folio_descs[folio_index].length = PAGE_SIZE;
+       ap->descs[folio_index].offset = 0;
+       ap->descs[folio_index].length = PAGE_SIZE;
 
        inc_wb_stat(&inode_to_bdi(inode)->wb, WB_WRITEBACK);
        node_stat_add_folio(tmp_folio, NR_WRITEBACK_TEMP);
@@ -2234,10 +2230,10 @@ static bool fuse_pages_realloc(struct fuse_fill_wb_data *data)
                return false;
 
        memcpy(folios, ap->folios, sizeof(struct folio *) * ap->num_folios);
-       memcpy(descs, ap->folio_descs, sizeof(struct fuse_folio_desc) * ap->num_folios);
+       memcpy(descs, ap->descs, sizeof(struct fuse_folio_desc) * ap->num_folios);
        kfree(ap->folios);
        ap->folios = folios;
-       ap->folio_descs = descs;
+       ap->descs = descs;
        data->max_folios = nfolios;
 
        return true;
index d26d278..d35c37c 100644 (file)
@@ -285,12 +285,6 @@ struct fuse_arg {
        void *value;
 };
 
-/** FUSE page descriptor */
-struct fuse_page_desc {
-       unsigned int length;
-       unsigned int offset;
-};
-
 /** FUSE folio descriptor */
 struct fuse_folio_desc {
        unsigned int length;
@@ -325,19 +319,9 @@ struct fuse_args {
 
 struct fuse_args_pages {
        struct fuse_args args;
-       union {
-               struct {
-                       struct page **pages;
-                       struct fuse_page_desc *descs;
-                       unsigned int num_pages;
-               };
-               struct {
-                       struct folio **folios;
-                       struct fuse_folio_desc *folio_descs;
-                       unsigned int num_folios;
-               };
-       };
-       bool uses_folios;
+       struct folio **folios;
+       struct fuse_folio_desc *descs;
+       unsigned int num_folios;
 };
 
 struct fuse_release_args {
index 1c77d8a..2d9abf4 100644 (file)
@@ -251,12 +251,12 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
        BUILD_BUG_ON(sizeof(struct fuse_ioctl_iovec) * FUSE_IOCTL_MAX_IOV > PAGE_SIZE);
 
        err = -ENOMEM;
-       ap.folios = fuse_folios_alloc(fm->fc->max_pages, GFP_KERNEL, &ap.folio_descs);
+       ap.folios = fuse_folios_alloc(fm->fc->max_pages, GFP_KERNEL, &ap.descs);
        iov_page = (struct iovec *) __get_free_page(GFP_KERNEL);
        if (!ap.folios || !iov_page)
                goto out;
 
-       fuse_folio_descs_length_init(ap.folio_descs, 0, fm->fc->max_pages);
+       fuse_folio_descs_length_init(ap.descs, 0, fm->fc->max_pages);
 
        /*
         * If restricted, initialize IO parameters as encoded in @cmd.
@@ -306,7 +306,6 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
        err = -ENOMEM;
        if (max_pages > fm->fc->max_pages)
                goto out;
-       ap.uses_folios = true;
        while (ap.num_folios < max_pages) {
                ap.folios[ap.num_folios] = folio_alloc(GFP_KERNEL | __GFP_HIGHMEM, 0);
                if (!ap.folios[ap.num_folios])
index fd0eff1..a2deead 100644 (file)
@@ -346,10 +346,9 @@ static int fuse_readdir_uncached(struct file *file, struct dir_context *ctx)
 
        plus = fuse_use_readdirplus(inode, ctx);
        ap->args.out_pages = true;
-       ap->uses_folios = true;
        ap->num_folios = 1;
        ap->folios = &folio;
-       ap->folio_descs = &desc;
+       ap->descs = &desc;
        if (plus) {
                attr_version = fuse_get_attr_version(fm->fc);
                fuse_read_args_fill(&ia, file, ctx->pos, PAGE_SIZE,
index 9f0d98c..d88d3fc 100644 (file)
@@ -765,7 +765,6 @@ static void virtio_fs_request_complete(struct fuse_req *req,
        struct fuse_args *args;
        struct fuse_args_pages *ap;
        unsigned int len, i, thislen;
-       struct page *page;
        struct folio *folio;
 
        /*
@@ -778,29 +777,15 @@ static void virtio_fs_request_complete(struct fuse_req *req,
        if (args->out_pages && args->page_zeroing) {
                len = args->out_args[args->out_numargs - 1].size;
                ap = container_of(args, typeof(*ap), args);
-               if (ap->uses_folios) {
-                       for (i = 0; i < ap->num_folios; i++) {
-                               thislen = ap->folio_descs[i].length;
-                               if (len < thislen) {
-                                       WARN_ON(ap->folio_descs[i].offset);
-                                       folio = ap->folios[i];
-                                       folio_zero_segment(folio, len, thislen);
-                                       len = 0;
-                               } else {
-                                       len -= thislen;
-                               }
-                       }
-               } else {
-                       for (i = 0; i < ap->num_pages; i++) {
-                               thislen = ap->descs[i].length;
-                               if (len < thislen) {
-                                       WARN_ON(ap->descs[i].offset);
-                                       page = ap->pages[i];
-                                       zero_user_segment(page, len, thislen);
-                                       len = 0;
-                               } else {
-                                       len -= thislen;
-                               }
+               for (i = 0; i < ap->num_folios; i++) {
+                       thislen = ap->descs[i].length;
+                       if (len < thislen) {
+                               WARN_ON(ap->descs[i].offset);
+                               folio = ap->folios[i];
+                               folio_zero_segment(folio, len, thislen);
+                               len = 0;
+                       } else {
+                               len -= thislen;
                        }
                }
        }
@@ -1287,22 +1272,16 @@ static void virtio_fs_send_interrupt(struct fuse_iqueue *fiq, struct fuse_req *r
 }
 
 /* Count number of scatter-gather elements required */
-static unsigned int sg_count_fuse_pages(struct fuse_args_pages *ap,
-                                       unsigned int total_len)
+static unsigned int sg_count_fuse_folios(struct fuse_folio_desc *folio_descs,
+                                        unsigned int num_folios,
+                                        unsigned int total_len)
 {
        unsigned int i;
        unsigned int this_len;
 
-       if (ap->uses_folios) {
-               for (i = 0; i < ap->num_folios && total_len; i++) {
-                       this_len =  min(ap->folio_descs[i].length, total_len);
-                       total_len -= this_len;
-               }
-       } else {
-               for (i = 0; i < ap->num_pages && total_len; i++) {
-                       this_len =  min(ap->descs[i].length, total_len);
-                       total_len -= this_len;
-               }
+       for (i = 0; i < num_folios && total_len; i++) {
+               this_len =  min(folio_descs[i].length, total_len);
+               total_len -= this_len;
        }
 
        return i;
@@ -1320,7 +1299,8 @@ static unsigned int sg_count_fuse_req(struct fuse_req *req)
 
        if (args->in_pages) {
                size = args->in_args[args->in_numargs - 1].size;
-               total_sgs += sg_count_fuse_pages(ap, size);
+               total_sgs += sg_count_fuse_folios(ap->descs, ap->num_folios,
+                                                 size);
        }
 
        if (!test_bit(FR_ISREPLY, &req->flags))
@@ -1333,35 +1313,28 @@ static unsigned int sg_count_fuse_req(struct fuse_req *req)
 
        if (args->out_pages) {
                size = args->out_args[args->out_numargs - 1].size;
-               total_sgs += sg_count_fuse_pages(ap, size);
+               total_sgs += sg_count_fuse_folios(ap->descs, ap->num_folios,
+                                                 size);
        }
 
        return total_sgs;
 }
 
-/* Add pages/folios to scatter-gather list and return number of elements used */
-static unsigned int sg_init_fuse_pages(struct scatterlist *sg,
-                                      struct fuse_args_pages *ap,
-                                      unsigned int total_len)
+/* Add folios to scatter-gather list and return number of elements used */
+static unsigned int sg_init_fuse_folios(struct scatterlist *sg,
+                                       struct folio **folios,
+                                       struct fuse_folio_desc *folio_descs,
+                                       unsigned int num_folios,
+                                       unsigned int total_len)
 {
        unsigned int i;
        unsigned int this_len;
 
-       if (ap->uses_folios) {
-               for (i = 0; i < ap->num_folios && total_len; i++) {
-                       sg_init_table(&sg[i], 1);
-                       this_len =  min(ap->folio_descs[i].length, total_len);
-                       sg_set_folio(&sg[i], ap->folios[i], this_len,
-                                    ap->folio_descs[i].offset);
-                       total_len -= this_len;
-               }
-       } else {
-               for (i = 0; i < ap->num_pages && total_len; i++) {
-                       sg_init_table(&sg[i], 1);
-                       this_len =  min(ap->descs[i].length, total_len);
-                       sg_set_page(&sg[i], ap->pages[i], this_len, ap->descs[i].offset);
-                       total_len -= this_len;
-               }
+       for (i = 0; i < num_folios && total_len; i++) {
+               sg_init_table(&sg[i], 1);
+               this_len =  min(folio_descs[i].length, total_len);
+               sg_set_folio(&sg[i], folios[i], this_len, folio_descs[i].offset);
+               total_len -= this_len;
        }
 
        return i;
@@ -1385,8 +1358,10 @@ static unsigned int sg_init_fuse_args(struct scatterlist *sg,
                sg_init_one(&sg[total_sgs++], argbuf, len);
 
        if (argpages)
-               total_sgs += sg_init_fuse_pages(&sg[total_sgs], ap,
-                                               args[numargs - 1].size);
+               total_sgs += sg_init_fuse_folios(&sg[total_sgs],
+                                                ap->folios, ap->descs,
+                                                ap->num_folios,
+                                                args[numargs - 1].size);
 
        if (len_used)
                *len_used = len;