[RFC PATCH 00/12] smb3: Add iter helpers and use iov_iters down to the network transport

From: David Howells
Date: Tue Nov 01 2022 - 12:32:45 EST



Hi Steve, Al, Christoph,

Here's an updated version of a subset of my branch to make the cifs/smb3
driver pass iov_iters down to the lowest layers where they can be passed to
the network transport.

The first couple of patches provide iov_iter general stuff:

(1) Move the FOLL_* flags to linux/mm_types.h so that linux/uio.h can make
use of them.

(2) Add a function to extract/get/pin pages from an iterator as a future
replacement for iov_iter_get_pages*(). It also adds a function by
which the caller can determine which of "extract/get/pin" the
extraction function will actually do to aid in cleaning up.

Then there are a couple of patches that add stuff to netfslib that I want
to use there as well as in cifs:

(3) Add a netfslib function to use (2) to extract pages from an ITER_IOBUF
or ITER_UBUF iterator into an ITER_BVEC iterator.

(4) Add a netfslib function to use (2) to extract pages from an iterator
that's of type ITER_UBUF/IOVEC/BVEC/KVEC/XARRAY and add them to a
scatterlist. The function in (2) is used for a UBUF and IOVEC
iterators, so those need cleaning up afterwards; BVEC and XARRAY
iterators can be rendered into elements that span multiple pages.

Then there are some cifs helpers that work with iterators:

(5) Implement cifs_splice_read() to use an ITER_BVEC rather than an
ITER_PIPE, bulk-allocating the pages, attaching them to the bvec,
doing the I/O and then pushing the pages into the pipe. This avoids
the problem with cifs wanting to split the pipe iterator in a later
patch.

(6) Add a function to walk through an ITER_BVEC/KVEC/XARRAY iterator and
add elements to an RDMA SGE list. Only the DMA addresses are stored,
and an element may span multiple pages (say if an xarray contains a
multipage folio).

(7) Add a function to walk through an ITER_BVEC/KVEC/XARRAY iterator and
pass the contents into a shash function.

(8) Add functions to walk through an ITER_XARRAY iterator and perform
various sorts of cleanup on the folios held therein, to be used on I/o
completion.

(9) Add a function to read from the transport TCP socket directly into an
iterator.

Then come the patches that actually do the work of iteratorising cifs:

(10) The main patch. Replace page lists with iterators. It extracts the
pages from ITER_UBUF and ITER_IOVEC iterators to an ITER_BVEC
iterator, pinning or getting refs on them, before passing them down as
the I/O may be done from a worker thread.

The iterator is extracted into a scatterlist in order to talk to the
crypto interface or to do RDMA.

(11) In the cifs RDMA code, extract the iterator into an RDMA SGE[] list,
removing the scatterlist intermediate - at least for smbd_send().
There appear to be other ways for cifs to talk to the RDMA layer that
don't go through that that I haven't managed to work out.

(12) Remove a chunk of now-unused code.

Note also that I haven't managed to test all the combinations of transport.
Samba doesn't support RDMA and ksmbd doesn't support encryption. I can
test them separately, but not together. That said, rdma, sign, seal and
sign+seal seem to work.

I've pushed the patches here also:

https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/log/?h=cifs-for-viro

Note that this is based on a merge of Al's work.iov_iter branch with
v6.1-rc2.

David

Link: https://lore.kernel.org/r/166697254399.61150.1256557652599252121.stgit@xxxxxxxxxxxxxxxxxxxxxx/
---
David Howells (12):
mm: Move FOLL_* defs to mm_types.h
iov_iter: Add a function to extract a page list from an iterator
netfs: Add a function to extract a UBUF or IOVEC into a BVEC iterator
netfs: Add a function to extract an iterator into a scatterlist
cifs: Implement splice_read to pass down ITER_BVEC not ITER_PIPE
cifs: Add a function to build an RDMA SGE list from an iterator
cifs: Add a function to Hash the contents of an iterator
cifs: Add some helper functions
cifs: Add a function to read into an iter from a socket
cifs: Change the I/O paths to use an iterator rather than a page list
cifs: Build the RDMA SGE list directly from an iterator
cifs: Remove unused code


fs/cifs/Kconfig | 1 +
fs/cifs/cifsencrypt.c | 172 +++-
fs/cifs/cifsfs.c | 12 +-
fs/cifs/cifsfs.h | 6 +
fs/cifs/cifsglob.h | 31 +-
fs/cifs/cifsproto.h | 11 +-
fs/cifs/cifssmb.c | 13 +-
fs/cifs/connect.c | 16 +
fs/cifs/file.c | 1793 ++++++++++++++++++--------------------
fs/cifs/fscache.c | 22 +-
fs/cifs/fscache.h | 10 +-
fs/cifs/misc.c | 127 +--
fs/cifs/smb2ops.c | 378 ++++----
fs/cifs/smb2pdu.c | 45 +-
fs/cifs/smbdirect.c | 503 +++++++----
fs/cifs/smbdirect.h | 4 +-
fs/cifs/transport.c | 57 +-
fs/netfs/Makefile | 1 +
fs/netfs/iterator.c | 346 ++++++++
include/linux/mm.h | 74 --
include/linux/mm_types.h | 73 ++
include/linux/netfs.h | 5 +
include/linux/uio.h | 29 +
lib/iov_iter.c | 333 +++++++
24 files changed, 2390 insertions(+), 1672 deletions(-)
create mode 100644 fs/netfs/iterator.c