From a669c2df36db5fa7a2674ec5ae10548760702f99 Mon Sep 17 00:00:00 2001 From: Joanne Koong Date: Thu, 24 Oct 2024 10:17:57 -0700 Subject: fuse: support folios in struct fuse_args_pages and fuse_copy_pages() This adds support in struct fuse_args_pages and fuse_copy_pages() for using folios instead of pages for transferring data. Both folios and pages must be supported right now in struct fuse_args_pages and fuse_copy_pages() until all request types have been converted to use folios. Once all have been converted, then struct fuse_args_pages and fuse_copy_pages() will only support folios. Right now in fuse, all folios are one page (large folios are not yet supported). As such, copying folio->page is sufficient for copying the entire folio in fuse_copy_pages(). No functional changes. Signed-off-by: Joanne Koong Reviewed-by: Josef Bacik Signed-off-by: Miklos Szeredi --- fs/fuse/dev.c | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) (limited to 'fs/fuse/dev.c') diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index e25804097ffb..70da1184a3f6 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -1028,17 +1028,41 @@ 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_pages && (nbytes || zeroing); i++) { - int err; - unsigned int offset = ap->descs[i].offset; - unsigned int count = min(nbytes, ap->descs[i].length); + orig = pagep = &ap->folios[i]->page; - err = fuse_copy_page(cs, &ap->pages[i], offset, count, zeroing); - if (err) - return err; + 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); - nbytes -= count; + err = fuse_copy_page(cs, &ap->pages[i], offset, count, zeroing); + if (err) + return err; + + nbytes -= count; + } } return 0; } -- cgit v1.2.3