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 <dhowells@redhat.com> cc: Steve French <sfrench@samba.org> cc: Paulo Alcantara <pc@manguebit.com> cc: Tom Talpey <tom@talpey.com> cc: Enzo Matsumiya <ematsumiya@suse.de> cc: linux-cifs@vger.kernel.org Link: https://lore.kernel.org/r/20240814203850.2240469-15-dhowells@redhat.com/ # v2 Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
parent
197a3de607
commit
c45ebd636c
@ -6,6 +6,7 @@
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/folio_queue.h>
|
||||
#include "smbdirect.h"
|
||||
#include "cifs_debug.h"
|
||||
#include "cifsproto.h"
|
||||
@ -2463,6 +2464,8 @@ static ssize_t smb_extract_bvec_to_rdma(struct iov_iter *iter,
|
||||
start = 0;
|
||||
}
|
||||
|
||||
if (ret > 0)
|
||||
iov_iter_advance(iter, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2519,6 +2522,65 @@ static ssize_t smb_extract_kvec_to_rdma(struct iov_iter *iter,
|
||||
start = 0;
|
||||
}
|
||||
|
||||
if (ret > 0)
|
||||
iov_iter_advance(iter, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract folio fragments from a FOLIOQ-class iterator and add them to an RDMA
|
||||
* list. The folios are not pinned.
|
||||
*/
|
||||
static ssize_t smb_extract_folioq_to_rdma(struct iov_iter *iter,
|
||||
struct smb_extract_to_rdma *rdma,
|
||||
ssize_t maxsize)
|
||||
{
|
||||
const struct folio_queue *folioq = iter->folioq;
|
||||
unsigned int slot = iter->folioq_slot;
|
||||
ssize_t ret = 0;
|
||||
size_t offset = iter->iov_offset;
|
||||
|
||||
BUG_ON(!folioq);
|
||||
|
||||
if (slot >= folioq_nr_slots(folioq)) {
|
||||
folioq = folioq->next;
|
||||
if (WARN_ON_ONCE(!folioq))
|
||||
return -EIO;
|
||||
slot = 0;
|
||||
}
|
||||
|
||||
do {
|
||||
struct folio *folio = folioq_folio(folioq, slot);
|
||||
size_t fsize = folioq_folio_size(folioq, slot);
|
||||
|
||||
if (offset < fsize) {
|
||||
size_t part = umin(maxsize - ret, fsize - offset);
|
||||
|
||||
if (!smb_set_sge(rdma, folio_page(folio, 0), offset, part))
|
||||
return -EIO;
|
||||
|
||||
offset += part;
|
||||
ret += part;
|
||||
}
|
||||
|
||||
if (offset >= fsize) {
|
||||
offset = 0;
|
||||
slot++;
|
||||
if (slot >= folioq_nr_slots(folioq)) {
|
||||
if (!folioq->next) {
|
||||
WARN_ON_ONCE(ret < iter->count);
|
||||
break;
|
||||
}
|
||||
folioq = folioq->next;
|
||||
slot = 0;
|
||||
}
|
||||
}
|
||||
} while (rdma->nr_sge < rdma->max_sge || maxsize > 0);
|
||||
|
||||
iter->folioq = folioq;
|
||||
iter->folioq_slot = slot;
|
||||
iter->iov_offset = offset;
|
||||
iter->count -= ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2563,6 +2625,8 @@ static ssize_t smb_extract_xarray_to_rdma(struct iov_iter *iter,
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
if (ret > 0)
|
||||
iov_iter_advance(iter, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2590,6 +2654,9 @@ static ssize_t smb_extract_iter_to_rdma(struct iov_iter *iter, size_t len,
|
||||
case ITER_KVEC:
|
||||
ret = smb_extract_kvec_to_rdma(iter, rdma, len);
|
||||
break;
|
||||
case ITER_FOLIOQ:
|
||||
ret = smb_extract_folioq_to_rdma(iter, rdma, len);
|
||||
break;
|
||||
case ITER_XARRAY:
|
||||
ret = smb_extract_xarray_to_rdma(iter, rdma, len);
|
||||
break;
|
||||
@ -2598,9 +2665,7 @@ static ssize_t smb_extract_iter_to_rdma(struct iov_iter *iter, size_t len,
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (ret > 0) {
|
||||
iov_iter_advance(iter, ret);
|
||||
} else if (ret < 0) {
|
||||
if (ret < 0) {
|
||||
while (rdma->nr_sge > before) {
|
||||
struct ib_sge *sge = &rdma->sge[rdma->nr_sge--];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user