Skip to content

Commit c45ebd6

Browse files
dhowellsbrauner
authored andcommitted
cifs: Provide the capability to extract from ITER_FOLIOQ to RDMA SGEs
Make smb_extract_iter_to_rdma() extract page fragments from an ITER_FOLIOQ iterator into RDMA SGEs. Signed-off-by: David Howells <[email protected]> cc: Steve French <[email protected]> cc: Paulo Alcantara <[email protected]> cc: Tom Talpey <[email protected]> cc: Enzo Matsumiya <[email protected]> cc: [email protected] Link: https://lore.kernel.org/r/[email protected]/ # v2 Signed-off-by: Christian Brauner <[email protected]>
1 parent 197a3de commit c45ebd6

File tree

1 file changed

+68
-3
lines changed

1 file changed

+68
-3
lines changed

fs/smb/client/smbdirect.c

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
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

Comments
 (0)