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>