Skip to content

Commit 29279e1

Browse files
joannekoongMiklos Szeredi
authored andcommitted
fuse: add support in virtio for requests using folios
Until all requests have been converted to use folios instead of pages, virtio will need to support both types. Once all requests have been converted, then virtio will support just folios. 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 a669c2d commit 29279e1

File tree

1 file changed

+56
-31
lines changed

1 file changed

+56
-31
lines changed

fs/fuse/virtio_fs.c

Lines changed: 56 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,7 @@ static void virtio_fs_request_complete(struct fuse_req *req,
766766
struct fuse_args_pages *ap;
767767
unsigned int len, i, thislen;
768768
struct page *page;
769+
struct folio *folio;
769770

770771
/*
771772
* TODO verify that server properly follows FUSE protocol
@@ -777,15 +778,29 @@ static void virtio_fs_request_complete(struct fuse_req *req,
777778
if (args->out_pages && args->page_zeroing) {
778779
len = args->out_args[args->out_numargs - 1].size;
779780
ap = container_of(args, typeof(*ap), args);
780-
for (i = 0; i < ap->num_pages; i++) {
781-
thislen = ap->descs[i].length;
782-
if (len < thislen) {
783-
WARN_ON(ap->descs[i].offset);
784-
page = ap->pages[i];
785-
zero_user_segment(page, len, thislen);
786-
len = 0;
787-
} else {
788-
len -= thislen;
781+
if (ap->uses_folios) {
782+
for (i = 0; i < ap->num_folios; i++) {
783+
thislen = ap->folio_descs[i].length;
784+
if (len < thislen) {
785+
WARN_ON(ap->folio_descs[i].offset);
786+
folio = ap->folios[i];
787+
folio_zero_segment(folio, len, thislen);
788+
len = 0;
789+
} else {
790+
len -= thislen;
791+
}
792+
}
793+
} else {
794+
for (i = 0; i < ap->num_pages; i++) {
795+
thislen = ap->descs[i].length;
796+
if (len < thislen) {
797+
WARN_ON(ap->descs[i].offset);
798+
page = ap->pages[i];
799+
zero_user_segment(page, len, thislen);
800+
len = 0;
801+
} else {
802+
len -= thislen;
803+
}
789804
}
790805
}
791806
}
@@ -1272,16 +1287,22 @@ static void virtio_fs_send_interrupt(struct fuse_iqueue *fiq, struct fuse_req *r
12721287
}
12731288

12741289
/* Count number of scatter-gather elements required */
1275-
static unsigned int sg_count_fuse_pages(struct fuse_page_desc *page_descs,
1276-
unsigned int num_pages,
1277-
unsigned int total_len)
1290+
static unsigned int sg_count_fuse_pages(struct fuse_args_pages *ap,
1291+
unsigned int total_len)
12781292
{
12791293
unsigned int i;
12801294
unsigned int this_len;
12811295

1282-
for (i = 0; i < num_pages && total_len; i++) {
1283-
this_len = min(page_descs[i].length, total_len);
1284-
total_len -= this_len;
1296+
if (ap->uses_folios) {
1297+
for (i = 0; i < ap->num_folios && total_len; i++) {
1298+
this_len = min(ap->folio_descs[i].length, total_len);
1299+
total_len -= this_len;
1300+
}
1301+
} else {
1302+
for (i = 0; i < ap->num_pages && total_len; i++) {
1303+
this_len = min(ap->descs[i].length, total_len);
1304+
total_len -= this_len;
1305+
}
12851306
}
12861307

12871308
return i;
@@ -1299,8 +1320,7 @@ static unsigned int sg_count_fuse_req(struct fuse_req *req)
12991320

13001321
if (args->in_pages) {
13011322
size = args->in_args[args->in_numargs - 1].size;
1302-
total_sgs += sg_count_fuse_pages(ap->descs, ap->num_pages,
1303-
size);
1323+
total_sgs += sg_count_fuse_pages(ap, size);
13041324
}
13051325

13061326
if (!test_bit(FR_ISREPLY, &req->flags))
@@ -1313,28 +1333,35 @@ static unsigned int sg_count_fuse_req(struct fuse_req *req)
13131333

13141334
if (args->out_pages) {
13151335
size = args->out_args[args->out_numargs - 1].size;
1316-
total_sgs += sg_count_fuse_pages(ap->descs, ap->num_pages,
1317-
size);
1336+
total_sgs += sg_count_fuse_pages(ap, size);
13181337
}
13191338

13201339
return total_sgs;
13211340
}
13221341

1323-
/* Add pages to scatter-gather list and return number of elements used */
1342+
/* Add pages/folios to scatter-gather list and return number of elements used */
13241343
static unsigned int sg_init_fuse_pages(struct scatterlist *sg,
1325-
struct page **pages,
1326-
struct fuse_page_desc *page_descs,
1327-
unsigned int num_pages,
1344+
struct fuse_args_pages *ap,
13281345
unsigned int total_len)
13291346
{
13301347
unsigned int i;
13311348
unsigned int this_len;
13321349

1333-
for (i = 0; i < num_pages && total_len; i++) {
1334-
sg_init_table(&sg[i], 1);
1335-
this_len = min(page_descs[i].length, total_len);
1336-
sg_set_page(&sg[i], pages[i], this_len, page_descs[i].offset);
1337-
total_len -= this_len;
1350+
if (ap->uses_folios) {
1351+
for (i = 0; i < ap->num_folios && total_len; i++) {
1352+
sg_init_table(&sg[i], 1);
1353+
this_len = min(ap->folio_descs[i].length, total_len);
1354+
sg_set_folio(&sg[i], ap->folios[i], this_len,
1355+
ap->folio_descs[i].offset);
1356+
total_len -= this_len;
1357+
}
1358+
} else {
1359+
for (i = 0; i < ap->num_pages && total_len; i++) {
1360+
sg_init_table(&sg[i], 1);
1361+
this_len = min(ap->descs[i].length, total_len);
1362+
sg_set_page(&sg[i], ap->pages[i], this_len, ap->descs[i].offset);
1363+
total_len -= this_len;
1364+
}
13381365
}
13391366

13401367
return i;
@@ -1358,9 +1385,7 @@ static unsigned int sg_init_fuse_args(struct scatterlist *sg,
13581385
sg_init_one(&sg[total_sgs++], argbuf, len);
13591386

13601387
if (argpages)
1361-
total_sgs += sg_init_fuse_pages(&sg[total_sgs],
1362-
ap->pages, ap->descs,
1363-
ap->num_pages,
1388+
total_sgs += sg_init_fuse_pages(&sg[total_sgs], ap,
13641389
args[numargs - 1].size);
13651390

13661391
if (len_used)

0 commit comments

Comments
 (0)