@@ -460,7 +460,6 @@ 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;
@@ -1028,37 +1028,23 @@ 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->folio_descs[i].offset;
+ unsigned int count = min(nbytes, ap->folio_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;
-
- /* Check if the folio was replaced in the page cache */
- 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;
- }
+ /* Check if the folio was replaced in the page cache */
+ if (pagep != orig)
+ ap->folios[i] = page_folio(pagep);
}
return 0;
}
@@ -1769,7 +1755,6 @@ 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_folios);
- ap->uses_folios = true;
args = &ap->args;
args->nodeid = outarg->nodeid;
@@ -1590,7 +1590,6 @@ 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,
@@ -747,7 +747,6 @@ 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);
if (!ia->ap.folios) {
@@ -873,7 +872,6 @@ 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,
@@ -1309,7 +1307,6 @@ static ssize_t fuse_perform_write(struct kiocb *iocb, struct iov_iter *ii)
unsigned int nr_folios = fuse_wr_folios(pos, iov_iter_count(ii),
fc->max_pages);
- ap->uses_folios = true;
ap->folios = fuse_folios_alloc(nr_folios, GFP_KERNEL, &ap->folio_descs);
if (!ap->folios) {
err = -ENOMEM;
@@ -2063,7 +2060,6 @@ 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);
if (!ap->folios) {
kfree(wpa);
@@ -322,19 +322,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;
+ unsigned int num_folios;
+ struct fuse_folio_desc *folio_descs;
};
struct fuse_release_args {
@@ -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])
@@ -346,7 +346,6 @@ 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;
@@ -773,29 +773,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->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;
}
}
}
@@ -1282,22 +1268,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;
@@ -1315,7 +1295,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->folio_descs, ap->num_folios,
+ size);
}
if (!test_bit(FR_ISREPLY, &req->flags))
@@ -1328,35 +1309,29 @@ 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->folio_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;
@@ -1380,8 +1355,11 @@ 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->folio_descs,
+ ap->num_folios,
+ args[numargs - 1].size);
if (len_used)
*len_used = len;
All fuse requests use folios instead of pages for transferring data. Remove pages from the requests and exclusively use folios. No functional changes. Signed-off-by: Joanne Koong <joannelkoong@gmail.com> --- fs/fuse/cuse.c | 1 - fs/fuse/dev.c | 41 +++++++------------- fs/fuse/dir.c | 1 - fs/fuse/file.c | 4 -- fs/fuse/fuse_i.h | 16 ++------ fs/fuse/ioctl.c | 1 - fs/fuse/readdir.c | 1 - fs/fuse/virtio_fs.c | 94 +++++++++++++++++---------------------------- 8 files changed, 52 insertions(+), 107 deletions(-)