svn commit: r358771 - projects/nfs-over-tls/sys/fs/nfsclient
Rick Macklem
rmacklem at FreeBSD.org
Sun Mar 8 19:09:15 UTC 2020
Author: rmacklem
Date: Sun Mar 8 19:09:13 2020
New Revision: 358771
URL: https://svnweb.freebsd.org/changeset/base/358771
Log:
Add support for reception of ext_pgs mbufs to the NFS client.
There also includes changes to simplify the handling of the
mbuf chain for doing proxied writes to mirrored DSs, so that
the nfsm_copym() function was no longer needed and is deleted.
Modified:
projects/nfs-over-tls/sys/fs/nfsclient/nfs_clcomsubs.c
projects/nfs-over-tls/sys/fs/nfsclient/nfs_clkrpc.c
projects/nfs-over-tls/sys/fs/nfsclient/nfs_clrpcops.c
Modified: projects/nfs-over-tls/sys/fs/nfsclient/nfs_clcomsubs.c
==============================================================================
--- projects/nfs-over-tls/sys/fs/nfsclient/nfs_clcomsubs.c Sun Mar 8 19:02:30 2020 (r358770)
+++ projects/nfs-over-tls/sys/fs/nfsclient/nfs_clcomsubs.c Sun Mar 8 19:09:13 2020 (r358771)
@@ -158,15 +158,22 @@ nfsm_uiombuf(struct nfsrv_descript *nd, struct uio *ui
/*
* copies a uio scatter/gather list to an mbuf chain.
* This version returns the mbuf list and does not use "nd".
+ * It allocates mbuf(s) of NFSM_RNDUP(siz) and ensures that
+ * it is nul padded to a multiple of 4 bytes.
+ * Since mbufs are allocated by this function, they will
+ * always have space for an exact multiple of 4 bytes in
+ * each mbuf. This implies that the nul padding can be
+ * safely done without checking for available space in
+ * the mbuf data area (or page for M_NOMAP mbufs).
* NOTE: can ony handle iovcnt == 1
*/
struct mbuf *
-nfsm_uiombuflist(int flag, int maxextsiz, struct uio *uiop, int siz,
+nfsm_uiombuflist(bool doextpgs, int maxextsiz, struct uio *uiop, int siz,
struct mbuf **mbp, char **cpp)
{
char *uiocp;
struct mbuf *mp, *mp2, *firstmp;
- int xfer, left, mlen;
+ int i, left, mlen, rem, xfer;
int uiosiz, clflg, bextpg, bextpgsiz = 0;
char *mcp, *tcp;
@@ -176,7 +183,8 @@ nfsm_uiombuflist(int flag, int maxextsiz, struct uio *
clflg = 1;
else
clflg = 0;
- if ((flag & ND_EXTPG) != 0) {
+ rem = NFSM_RNDUP(siz) - siz;
+ if (doextpgs) {
mp = mb_alloc_ext_plus_pages(PAGE_SIZE, M_WAITOK,
false, mb_free_mext_pgs);
mcp = (char *)(void *)
@@ -199,12 +207,12 @@ nfsm_uiombuflist(int flag, int maxextsiz, struct uio *
left = siz;
uiosiz = left;
while (left > 0) {
- if ((flag & ND_EXTPG) != 0)
+ if (doextpgs)
mlen = bextpgsiz;
else
mlen = M_TRAILINGSPACE(mp);
if (mlen == 0) {
- if ((flag & ND_EXTPG) != 0) {
+ if (doextpgs) {
mp = nfsm_add_ext_pgs(mp, maxextsiz,
&bextpg);
mcp = (char *)(void *)PHYS_TO_DMAP(
@@ -231,7 +239,7 @@ nfsm_uiombuflist(int flag, int maxextsiz, struct uio *
left -= xfer;
uiocp += xfer;
mcp += xfer;
- if ((flag & ND_EXTPG) != 0) {
+ if (doextpgs) {
bextpgsiz -= xfer;
mp->m_ext.ext_pgs->last_pg_len += xfer;
}
@@ -243,6 +251,12 @@ nfsm_uiombuflist(int flag, int maxextsiz, struct uio *
uiop->uio_iov->iov_base = (void *)tcp;
uiop->uio_iov->iov_len -= uiosiz;
siz -= uiosiz;
+ }
+ for (i = 0; i < rem; i++) {
+ *mcp++ = '\0';
+ mp->m_len++;
+ if (doextpgs)
+ mp->m_ext.ext_pgs->last_pg_len++;
}
if (cpp != NULL)
*cpp = mcp;
Modified: projects/nfs-over-tls/sys/fs/nfsclient/nfs_clkrpc.c
==============================================================================
--- projects/nfs-over-tls/sys/fs/nfsclient/nfs_clkrpc.c Sun Mar 8 19:02:30 2020 (r358770)
+++ projects/nfs-over-tls/sys/fs/nfsclient/nfs_clkrpc.c Sun Mar 8 19:09:13 2020 (r358771)
@@ -73,6 +73,7 @@ nfscb_program(struct svc_req *rqst, SVCXPRT *xprt)
struct nfsrv_descript nd;
int cacherep, credflavor;
+printf("cbprogram proc=%d\n", rqst->rq_proc);
memset(&nd, 0, sizeof(nd));
if (rqst->rq_proc != NFSPROC_NULL &&
rqst->rq_proc != NFSV4PROC_CBCOMPOUND) {
@@ -92,7 +93,8 @@ nfscb_program(struct svc_req *rqst, SVCXPRT *xprt)
rqst->rq_args = NULL;
newnfs_realign(&nd.nd_mrep, M_WAITOK);
nd.nd_md = nd.nd_mrep;
- nd.nd_dpos = mtod(nd.nd_md, caddr_t);
+printf("cbreq nd_md=%p offs=%d\n", nd.nd_md, rqst->rq_xprt->xp_mbufoffs);
+ nfsm_set(&nd, rqst->rq_xprt->xp_mbufoffs, false);
nd.nd_nam = svc_getrpccaller(rqst);
nd.nd_nam2 = rqst->rq_addr;
nd.nd_mreq = NULL;
@@ -265,6 +267,7 @@ nfscbd_nfsd(struct thread *td, struct nfsd_nfscbd_args
nfscbd_pool->sp_minthreads = 4;
nfscbd_pool->sp_maxthreads = 4;
+printf("CBpool\n");
svc_run(nfscbd_pool);
rpc_gss_clear_svc_name_call(NFS_CALLBCKPROG, NFSV4_CBVERS);
Modified: projects/nfs-over-tls/sys/fs/nfsclient/nfs_clrpcops.c
==============================================================================
--- projects/nfs-over-tls/sys/fs/nfsclient/nfs_clrpcops.c Sun Mar 8 19:02:30 2020 (r358770)
+++ projects/nfs-over-tls/sys/fs/nfsclient/nfs_clrpcops.c Sun Mar 8 19:09:13 2020 (r358771)
@@ -78,6 +78,9 @@ extern int nfs_pnfsiothreads;
extern u_long sb_max_adj;
extern int nfs_maxcopyrange;
extern bool nfs_use_ext_pgs;
+#ifdef KERN_TLS
+extern u_int ktls_maxlen;
+#endif
NFSCLSTATEMUTEX;
int nfstest_outofseq = 0;
int nfscl_assumeposixlocks = 1;
@@ -162,7 +165,6 @@ static int nfscl_dofflayoutio(vnode_t, struct uio *, i
nfsv4stateid_t *, int, struct nfscldevinfo *, struct nfscllayout *,
struct nfsclflayout *, uint64_t, uint64_t, int, int, struct mbuf *,
struct nfsclwritedsdorpc *, struct ucred *, NFSPROC_T *);
-static struct mbuf *nfsm_copym(struct mbuf *, int, int);
static int nfsrpc_readds(vnode_t, struct uio *, nfsv4stateid_t *, int *,
struct nfsclds *, uint64_t, int, struct nfsfh *, int, int, int,
struct ucred *, NFSPROC_T *);
@@ -5691,7 +5693,7 @@ nfscl_doiods(vnode_t vp, struct uio *uiop, int *iomode
struct nfscllayout *layp;
struct nfscldevinfo *dip;
struct nfsclflayout *rflp;
- struct mbuf *m;
+ struct mbuf *m, *m2;
struct nfsclwritedsdorpc *drpc, *tdrpc;
nfsv4stateid_t stateid;
struct ucred *newcred;
@@ -5703,6 +5705,8 @@ nfscl_doiods(vnode_t vp, struct uio *uiop, int *iomode
size_t iovlen = 0;
off_t offs = 0;
ssize_t resid = 0;
+ int maxextsiz;
+ bool doextpgs;
if (!NFSHASPNFS(nmp) || nfscl_enablecallb == 0 || nfs_numnfscbd == 0 ||
(np->n_flag & NNOLAYOUT) != 0)
@@ -5796,8 +5800,23 @@ nfscl_doiods(vnode_t vp, struct uio *uiop, int *iomode
iovbase =
uiop->uio_iov->iov_base;
iovlen = uiop->uio_iov->iov_len;
- m = nfsm_uiombuflist(0, 0, uiop, len,
- NULL, NULL);
+ doextpgs = false;
+ maxextsiz = 0;
+ if ((NFSHASTLS(nmp) ||
+ (nfs_use_ext_pgs &&
+ xfer > MCLBYTES)) &&
+ PMAP_HAS_DMAP != 0) {
+ doextpgs = true;
+ maxextsiz = 16384;
+#ifdef KERN_TLS
+ maxextsiz = min(
+ TLS_MAX_MSG_SIZE_V10_2,
+ ktls_maxlen);
+#endif
+ }
+ m = nfsm_uiombuflist(doextpgs,
+ maxextsiz, uiop, len, NULL,
+ NULL);
}
tdrpc = drpc = malloc(sizeof(*drpc) *
(mirrorcnt - 1), M_TEMP, M_WAITOK |
@@ -5805,6 +5824,12 @@ nfscl_doiods(vnode_t vp, struct uio *uiop, int *iomode
}
}
for (i = firstmirror; i < mirrorcnt && error == 0; i++){
+ if (m != NULL && i < mirrorcnt - 1)
+ m2 = m_copym(m, 0, M_COPYALL, M_WAITOK);
+ else {
+ m2 = m;
+ m = NULL;
+ }
if ((layp->nfsly_flags & NFSLY_FLEXFILE) != 0) {
dev = rflp->nfsfl_ffm[i].dev;
dip = nfscl_getdevinfo(nmp->nm_clp, dev,
@@ -5821,7 +5846,7 @@ nfscl_doiods(vnode_t vp, struct uio *uiop, int *iomode
uiop, iomode, must_commit,
&eof, &stateid, rwaccess,
dip, layp, rflp, off, xfer,
- i, docommit, m, tdrpc,
+ i, docommit, m2, tdrpc,
newcred, p);
else
error = nfscl_doflayoutio(vp,
@@ -5830,12 +5855,13 @@ nfscl_doiods(vnode_t vp, struct uio *uiop, int *iomode
dip, layp, rflp, off, xfer,
docommit, newcred, p);
nfscl_reldevinfo(dip);
- } else
+ } else {
+ m_freem(m2);
error = EIO;
+ }
tdrpc++;
}
- if (m != NULL)
- m_freem(m);
+ m_freem(m);
tdrpc = drpc;
timo = hz / 50; /* Wait for 20msec. */
if (timo < 1)
@@ -5897,38 +5923,6 @@ nfscl_doiods(vnode_t vp, struct uio *uiop, int *iomode
}
/*
- * Make a copy of the mbuf chain and add an mbuf for null padding, as required.
- */
-static struct mbuf *
-nfsm_copym(struct mbuf *m, int off, int xfer)
-{
- struct mbuf *m2, *m3, *m4;
- uint32_t *tl;
- int rem;
-
- m2 = m_copym(m, off, xfer, M_WAITOK);
- rem = NFSM_RNDUP(xfer) - xfer;
- if (rem > 0) {
- /*
- * The zero padding to a multiple of 4 bytes is required by
- * the XDR. So that the mbufs copied by reference aren't
- * modified, add an mbuf with the zero'd bytes to the list.
- * rem will be a maximum of 3, so one zero'd uint32_t is
- * sufficient.
- */
- m3 = m2;
- while (m3->m_next != NULL)
- m3 = m3->m_next;
- NFSMGET(m4);
- tl = NFSMTOD(m4, uint32_t *);
- *tl = 0;
- mbuf_setlen(m4, rem);
- mbuf_setnext(m3, m4);
- }
- return (m2);
-}
-
-/*
* Find a file layout that will handle the first bytes of the requested
* range and return the information from it needed to the I/O operation.
*/
@@ -6179,7 +6173,18 @@ nfscl_dofflayoutio(vnode_t vp, struct uio *uiop, int *
NFSUNLOCKCLSTATE();
}
} else {
- m = nfsm_copym(mp, rel_off, xfer);
+ /*
+ * Split off the first xfer bytes of the mbuf
+ * chain.
+ */
+ m = mp;
+ if (xfer < len) {
+ if ((m->m_flags & M_NOMAP) != 0)
+ mp = mb_splitatpos_ext(m, xfer,
+ M_WAITOK);
+ else
+ mp = m_split(m, xfer, M_WAITOK);
+ }
NFSCL_DEBUG(4, "mcopy reloff=%d xfer=%jd\n",
rel_off, (uintmax_t)xfer);
/*
@@ -6198,6 +6203,8 @@ nfscl_dofflayoutio(vnode_t vp, struct uio *uiop, int *
xfer, fhp, m, dp->nfsdi_vers,
dp->nfsdi_minorvers, tcred, p);
NFSCL_DEBUG(4, "nfsio_writedsmir=%d\n", error);
+ if (xfer == len)
+ mp = NULL;
if (error != 0 && error != EACCES && error !=
ESTALE) {
NFSCL_DEBUG(4,
@@ -6216,6 +6223,7 @@ nfscl_dofflayoutio(vnode_t vp, struct uio *uiop, int *
if ((dp->nfsdi_flags & NFSDI_TIGHTCOUPLED) == 0)
NFSFREECRED(tcred);
}
+ m_freem(mp); /* In case errors occurred. */
NFSCL_DEBUG(4, "eo nfscl_dofflayoutio=%d\n", error);
return (error);
}
More information about the svn-src-projects
mailing list