Skip to content

Commit a669c2d

Browse files
joannekoongMiklos Szeredi
authored andcommitted
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 <[email protected]> Reviewed-by: Josef Bacik <[email protected]> Signed-off-by: Miklos Szeredi <[email protected]>
1 parent 8807f11 commit a669c2d

File tree

2 files changed

+51
-11
lines changed

2 files changed

+51
-11
lines changed

fs/fuse/dev.c

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,17 +1028,41 @@ static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes,
10281028
struct fuse_req *req = cs->req;
10291029
struct fuse_args_pages *ap = container_of(req->args, typeof(*ap), args);
10301030

1031+
if (ap->uses_folios) {
1032+
for (i = 0; i < ap->num_folios && (nbytes || zeroing); i++) {
1033+
int err;
1034+
unsigned int offset = ap->folio_descs[i].offset;
1035+
unsigned int count = min(nbytes, ap->folio_descs[i].length);
1036+
struct page *orig, *pagep;
10311037

1032-
for (i = 0; i < ap->num_pages && (nbytes || zeroing); i++) {
1033-
int err;
1034-
unsigned int offset = ap->descs[i].offset;
1035-
unsigned int count = min(nbytes, ap->descs[i].length);
1038+
orig = pagep = &ap->folios[i]->page;
10361039

1037-
err = fuse_copy_page(cs, &ap->pages[i], offset, count, zeroing);
1038-
if (err)
1039-
return err;
1040+
err = fuse_copy_page(cs, &pagep, offset, count, zeroing);
1041+
if (err)
1042+
return err;
1043+
1044+
nbytes -= count;
1045+
1046+
/*
1047+
* fuse_copy_page may have moved a page from a pipe
1048+
* instead of copying into our given page, so update
1049+
* the folios if it was replaced.
1050+
*/
1051+
if (pagep != orig)
1052+
ap->folios[i] = page_folio(pagep);
1053+
}
1054+
} else {
1055+
for (i = 0; i < ap->num_pages && (nbytes || zeroing); i++) {
1056+
int err;
1057+
unsigned int offset = ap->descs[i].offset;
1058+
unsigned int count = min(nbytes, ap->descs[i].length);
10401059

1041-
nbytes -= count;
1060+
err = fuse_copy_page(cs, &ap->pages[i], offset, count, zeroing);
1061+
if (err)
1062+
return err;
1063+
1064+
nbytes -= count;
1065+
}
10421066
}
10431067
return 0;
10441068
}

fs/fuse/fuse_i.h

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,12 @@ struct fuse_page_desc {
291291
unsigned int offset;
292292
};
293293

294+
/** FUSE folio descriptor */
295+
struct fuse_folio_desc {
296+
unsigned int length;
297+
unsigned int offset;
298+
};
299+
294300
struct fuse_args {
295301
uint64_t nodeid;
296302
uint32_t opcode;
@@ -319,9 +325,19 @@ struct fuse_args {
319325

320326
struct fuse_args_pages {
321327
struct fuse_args args;
322-
struct page **pages;
323-
struct fuse_page_desc *descs;
324-
unsigned int num_pages;
328+
union {
329+
struct {
330+
struct page **pages;
331+
struct fuse_page_desc *descs;
332+
unsigned int num_pages;
333+
};
334+
struct {
335+
struct folio **folios;
336+
struct fuse_folio_desc *folio_descs;
337+
unsigned int num_folios;
338+
};
339+
};
340+
bool uses_folios;
325341
};
326342

327343
struct fuse_release_args {

0 commit comments

Comments
 (0)