66 */
77#include <linux/module.h>
88#include <linux/highmem.h>
9+ #include <linux/folio_queue.h>
910#include "smbdirect.h"
1011#include "cifs_debug.h"
1112#include "cifsproto.h"
@@ -2463,6 +2464,8 @@ static ssize_t smb_extract_bvec_to_rdma(struct iov_iter *iter,
24632464 start = 0 ;
24642465 }
24652466
2467+ if (ret > 0 )
2468+ iov_iter_advance (iter , ret );
24662469 return ret ;
24672470}
24682471
@@ -2519,6 +2522,65 @@ static ssize_t smb_extract_kvec_to_rdma(struct iov_iter *iter,
25192522 start = 0 ;
25202523 }
25212524
2525+ if (ret > 0 )
2526+ iov_iter_advance (iter , ret );
2527+ return ret ;
2528+ }
2529+
2530+ /*
2531+ * Extract folio fragments from a FOLIOQ-class iterator and add them to an RDMA
2532+ * list. The folios are not pinned.
2533+ */
2534+ static ssize_t smb_extract_folioq_to_rdma (struct iov_iter * iter ,
2535+ struct smb_extract_to_rdma * rdma ,
2536+ ssize_t maxsize )
2537+ {
2538+ const struct folio_queue * folioq = iter -> folioq ;
2539+ unsigned int slot = iter -> folioq_slot ;
2540+ ssize_t ret = 0 ;
2541+ size_t offset = iter -> iov_offset ;
2542+
2543+ BUG_ON (!folioq );
2544+
2545+ if (slot >= folioq_nr_slots (folioq )) {
2546+ folioq = folioq -> next ;
2547+ if (WARN_ON_ONCE (!folioq ))
2548+ return - EIO ;
2549+ slot = 0 ;
2550+ }
2551+
2552+ do {
2553+ struct folio * folio = folioq_folio (folioq , slot );
2554+ size_t fsize = folioq_folio_size (folioq , slot );
2555+
2556+ if (offset < fsize ) {
2557+ size_t part = umin (maxsize - ret , fsize - offset );
2558+
2559+ if (!smb_set_sge (rdma , folio_page (folio , 0 ), offset , part ))
2560+ return - EIO ;
2561+
2562+ offset += part ;
2563+ ret += part ;
2564+ }
2565+
2566+ if (offset >= fsize ) {
2567+ offset = 0 ;
2568+ slot ++ ;
2569+ if (slot >= folioq_nr_slots (folioq )) {
2570+ if (!folioq -> next ) {
2571+ WARN_ON_ONCE (ret < iter -> count );
2572+ break ;
2573+ }
2574+ folioq = folioq -> next ;
2575+ slot = 0 ;
2576+ }
2577+ }
2578+ } while (rdma -> nr_sge < rdma -> max_sge || maxsize > 0 );
2579+
2580+ iter -> folioq = folioq ;
2581+ iter -> folioq_slot = slot ;
2582+ iter -> iov_offset = offset ;
2583+ iter -> count -= ret ;
25222584 return ret ;
25232585}
25242586
@@ -2563,6 +2625,8 @@ static ssize_t smb_extract_xarray_to_rdma(struct iov_iter *iter,
25632625 }
25642626
25652627 rcu_read_unlock ();
2628+ if (ret > 0 )
2629+ iov_iter_advance (iter , ret );
25662630 return ret ;
25672631}
25682632
@@ -2590,6 +2654,9 @@ static ssize_t smb_extract_iter_to_rdma(struct iov_iter *iter, size_t len,
25902654 case ITER_KVEC :
25912655 ret = smb_extract_kvec_to_rdma (iter , rdma , len );
25922656 break ;
2657+ case ITER_FOLIOQ :
2658+ ret = smb_extract_folioq_to_rdma (iter , rdma , len );
2659+ break ;
25932660 case ITER_XARRAY :
25942661 ret = smb_extract_xarray_to_rdma (iter , rdma , len );
25952662 break ;
@@ -2598,9 +2665,7 @@ static ssize_t smb_extract_iter_to_rdma(struct iov_iter *iter, size_t len,
25982665 return - EIO ;
25992666 }
26002667
2601- if (ret > 0 ) {
2602- iov_iter_advance (iter , ret );
2603- } else if (ret < 0 ) {
2668+ if (ret < 0 ) {
26042669 while (rdma -> nr_sge > before ) {
26052670 struct ib_sge * sge = & rdma -> sge [rdma -> nr_sge -- ];
26062671
0 commit comments