@@ -766,6 +766,7 @@ static void virtio_fs_request_complete(struct fuse_req *req,
766
766
struct fuse_args_pages * ap ;
767
767
unsigned int len , i , thislen ;
768
768
struct page * page ;
769
+ struct folio * folio ;
769
770
770
771
/*
771
772
* TODO verify that server properly follows FUSE protocol
@@ -777,15 +778,29 @@ static void virtio_fs_request_complete(struct fuse_req *req,
777
778
if (args -> out_pages && args -> page_zeroing ) {
778
779
len = args -> out_args [args -> out_numargs - 1 ].size ;
779
780
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
+ }
789
804
}
790
805
}
791
806
}
@@ -1272,16 +1287,22 @@ static void virtio_fs_send_interrupt(struct fuse_iqueue *fiq, struct fuse_req *r
1272
1287
}
1273
1288
1274
1289
/* 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 )
1278
1292
{
1279
1293
unsigned int i ;
1280
1294
unsigned int this_len ;
1281
1295
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
+ }
1285
1306
}
1286
1307
1287
1308
return i ;
@@ -1299,8 +1320,7 @@ static unsigned int sg_count_fuse_req(struct fuse_req *req)
1299
1320
1300
1321
if (args -> in_pages ) {
1301
1322
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 );
1304
1324
}
1305
1325
1306
1326
if (!test_bit (FR_ISREPLY , & req -> flags ))
@@ -1313,28 +1333,35 @@ static unsigned int sg_count_fuse_req(struct fuse_req *req)
1313
1333
1314
1334
if (args -> out_pages ) {
1315
1335
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 );
1318
1337
}
1319
1338
1320
1339
return total_sgs ;
1321
1340
}
1322
1341
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 */
1324
1343
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 ,
1328
1345
unsigned int total_len )
1329
1346
{
1330
1347
unsigned int i ;
1331
1348
unsigned int this_len ;
1332
1349
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
+ }
1338
1365
}
1339
1366
1340
1367
return i ;
@@ -1358,9 +1385,7 @@ static unsigned int sg_init_fuse_args(struct scatterlist *sg,
1358
1385
sg_init_one (& sg [total_sgs ++ ], argbuf , len );
1359
1386
1360
1387
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 ,
1364
1389
args [numargs - 1 ].size );
1365
1390
1366
1391
if (len_used )
0 commit comments