Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 8 Mar 2020 19:09:13 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r358771 - projects/nfs-over-tls/sys/fs/nfsclient
Message-ID:  <202003081909.028J9DvR036556@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202003081909.028J9DvR036556>