diff options
| -rw-r--r-- | fs/fuse/virtio_fs.c | 87 |
1 files changed, 56 insertions, 31 deletions
diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c index f68527891929..9f0d98cc20d3 100644 --- a/fs/fuse/virtio_fs.c +++ b/fs/fuse/virtio_fs.c @@ -766,6 +766,7 @@ static void virtio_fs_request_complete(struct fuse_req *req, struct fuse_args_pages *ap; unsigned int len, i, thislen; struct page *page; + struct folio *folio; /* * TODO verify that server properly follows FUSE protocol @@ -777,15 +778,29 @@ 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); - 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; + 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; + } } } } @@ -1272,16 +1287,22 @@ 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_page_desc *page_descs, - unsigned int num_pages, - unsigned int total_len) +static unsigned int sg_count_fuse_pages(struct fuse_args_pages *ap, + unsigned int total_len) { unsigned int i; unsigned int this_len; - for (i = 0; i < num_pages && total_len; i++) { - this_len = min(page_descs[i].length, total_len); - total_len -= 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; + } } return i; @@ -1299,8 +1320,7 @@ 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->descs, ap->num_pages, - size); + total_sgs += sg_count_fuse_pages(ap, size); } if (!test_bit(FR_ISREPLY, &req->flags)) @@ -1313,28 +1333,35 @@ 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->descs, ap->num_pages, - size); + total_sgs += sg_count_fuse_pages(ap, size); } return total_sgs; } -/* Add pages to scatter-gather list and return number of elements used */ +/* Add pages/folios to scatter-gather list and return number of elements used */ static unsigned int sg_init_fuse_pages(struct scatterlist *sg, - struct page **pages, - struct fuse_page_desc *page_descs, - unsigned int num_pages, + struct fuse_args_pages *ap, unsigned int total_len) { unsigned int i; unsigned int this_len; - for (i = 0; i < num_pages && total_len; i++) { - sg_init_table(&sg[i], 1); - this_len = min(page_descs[i].length, total_len); - sg_set_page(&sg[i], pages[i], this_len, page_descs[i].offset); - total_len -= 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; + } } return i; @@ -1358,9 +1385,7 @@ 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->pages, ap->descs, - ap->num_pages, + total_sgs += sg_init_fuse_pages(&sg[total_sgs], ap, args[numargs - 1].size); if (len_used) |
