Re: [PATCH 17/26] cifs: Support ITER_BVECQ in smb_extract_iter_to_rdma()
Stefan Metzmacher <[email protected]> Sun, 29 Mar 2026 12:36:08 +0200
| Newsgroups | dev.linux.lists.v9fs,dev.linux.lists.netfs,org.kernel.vger.ceph-devel,org.kernel.vger.linux-cifs,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel,org.kernel.vger.linux-nfs,org.ozlabs.lists.linux-erofs |
|---|---|
| Message-ID | <[email protected]> |
Hi David, this conflicts with my patches in ksmbd-for-next where we have this as smbdirect_map_sges_from_iter and shared between client and server. Can you rebase on ksmbd-for-next? Thanks! metze Am 26.03.26 um 11:45 schrieb David Howells: > Add support for ITER_BVECQ to smb_extract_iter_to_rdma(). > > Signed-off-by: David Howells <[email protected]> > cc: Paulo Alcantara <[email protected]> > cc: Matthew Wilcox <[email protected]> > cc: Christoph Hellwig <[email protected]> > cc: Steve French <[email protected]> > cc: Shyam Prasad N <[email protected]> > cc: Tom Talpey <[email protected]> > cc: [email protected] > cc: [email protected] > cc: [email protected] > --- > fs/smb/client/smbdirect.c | 60 +++++++++++++++++++++++++++++++++++++++ > 1 file changed, 60 insertions(+) > > diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c > index c79304012b08..f8a6be83db98 100644 > --- a/fs/smb/client/smbdirect.c > +++ b/fs/smb/client/smbdirect.c > @@ -3298,6 +3298,63 @@ static ssize_t smb_extract_folioq_to_rdma(struct iov_iter *iter, > return ret; > } > > +/* > + * Extract memory fragments from a BVECQ-class iterator and add them to an RDMA > + * list. The folios are not pinned. > + */ > +static ssize_t smb_extract_bvecq_to_rdma(struct iov_iter *iter, > + struct smb_extract_to_rdma *rdma, > + ssize_t maxsize) > +{ > + const struct bvecq *bq = iter->bvecq; > + unsigned int slot = iter->bvecq_slot; > + ssize_t ret = 0; > + size_t offset = iter->iov_offset; > + > + if (slot >= bq->nr_slots) { > + bq = bq->next; > + if (WARN_ON_ONCE(!bq)) > + return -EIO; > + slot = 0; > + } > + > + do { > + struct bio_vec *bv = &bq->bv[slot]; > + struct page *page = bv->bv_page; > + size_t bsize = bv->bv_len; > + > + if (offset < bsize) { > + size_t part = umin(maxsize, bsize - offset); > + > + if (!smb_set_sge(rdma, page, bv->bv_offset + offset, part)) > + return -EIO; > + > + offset += part; > + ret += part; > + maxsize -= part; > + } > + > + if (offset >= bsize) { > + offset = 0; > + slot++; > + if (slot >= bq->nr_slots) { > + if (!bq->next) { > + WARN_ON_ONCE(ret < iter->count); > + break; > + } > + bq = bq->next; > + slot = 0; > + } > + } > + } while (rdma->nr_sge < rdma->max_sge && maxsize > 0); > + > + iter->bvecq = bq; > + iter->bvecq_slot = slot; > + iter->iov_offset = offset; > + iter->count -= ret; > + return ret; > +} > + > /* > * Extract page fragments from up to the given amount of the source iterator > * and build up an RDMA list that refers to all of those bits. The RDMA list > @@ -3325,6 +3382,9 @@ static ssize_t smb_extract_iter_to_rdma(struct iov_iter *iter, size_t len, > case ITER_FOLIOQ: > ret = smb_extract_folioq_to_rdma(iter, rdma, len); > break; > + case ITER_BVECQ: > + ret = smb_extract_bvecq_to_rdma(iter, rdma, len); > + break; > default: > WARN_ON_ONCE(1); > return -EIO; >