Date: Sun, 10 May 2020 20:44:44 +0000 (UTC) From: Rick Macklem <rmacklem@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r360883 - in projects/nfs-over-tls/sys/fs: nfs nfsserver Message-ID: <202005102044.04AKiiC5019215@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rmacklem Date: Sun May 10 20:44:43 2020 New Revision: 360883 URL: https://svnweb.freebsd.org/changeset/base/360883 Log: Revert some of the code for dissecting the ext_pgs mbufs, since it is not currently needed. The code that dissects ext_pgs mbufs for NFS involves a lot of churn and removing will simplify merging to head. I will keep these patches around, in case they are needed someday. Modified: projects/nfs-over-tls/sys/fs/nfs/nfs_commonsubs.c projects/nfs-over-tls/sys/fs/nfs/nfs_var.h projects/nfs-over-tls/sys/fs/nfs/nfsm_subs.h projects/nfs-over-tls/sys/fs/nfsserver/nfs_nfsdport.c projects/nfs-over-tls/sys/fs/nfsserver/nfs_nfsdserv.c projects/nfs-over-tls/sys/fs/nfsserver/nfs_nfsdsubs.c Modified: projects/nfs-over-tls/sys/fs/nfs/nfs_commonsubs.c ============================================================================== --- projects/nfs-over-tls/sys/fs/nfs/nfs_commonsubs.c Sun May 10 20:28:38 2020 (r360882) +++ projects/nfs-over-tls/sys/fs/nfs/nfs_commonsubs.c Sun May 10 20:44:43 2020 (r360883) @@ -237,11 +237,6 @@ static void nfsrv_removeuser(struct nfsusrgrp *usrp, i static int nfsrv_getrefstr(struct nfsrv_descript *, u_char **, u_char **, int *, int *); static void nfsrv_refstrbigenough(int, u_char **, u_char **, int *); -static int nfsm_copyfrommbuf(struct nfsrv_descript *, char *, enum uio_seg, - int); -static int nfsm_copyfrommbuf_extpgs(struct nfsrv_descript *, char *, - enum uio_seg, int); -static struct mbuf *nfsm_splitatpgno(struct mbuf *, int, int); static struct { int op; @@ -641,11 +636,15 @@ nfscl_fillsattr(struct nfsrv_descript *nd, struct vatt int nfsm_mbufuio(struct nfsrv_descript *nd, struct uio *uiop, int siz) { - char *uiocp; + char *mbufcp, *uiocp; int xfer, left, len; + struct mbuf *mp; long uiosiz, rem; int error = 0; + mp = nd->nd_md; + mbufcp = nd->nd_dpos; + len = mtod(mp, caddr_t) + mp->m_len - mbufcp; rem = NFSM_RNDUP(siz) - siz; while (siz > 0) { if (uiop->uio_iovcnt <= 0 || uiop->uio_iov == NULL) { @@ -658,16 +657,35 @@ nfsm_mbufuio(struct nfsrv_descript *nd, struct uio *ui left = siz; uiosiz = left; while (left > 0) { - xfer = nfsm_copyfrommbuf(nd, uiocp, uiop->uio_segflg, - left); + while (len == 0) { + mp = mp->m_next; + if (mp == NULL) { + error = EBADRPC; + goto out; + } + mbufcp = mtod(mp, caddr_t); + len = mp->m_len; + KASSERT(len >= 0, + ("len %d, corrupted mbuf?", len)); + } + xfer = (left > len) ? len : left; +#ifdef notdef + /* Not Yet.. */ + if (uiop->uio_iov->iov_op != NULL) + (*(uiop->uio_iov->iov_op)) + (mbufcp, uiocp, xfer); + else +#endif + if (uiop->uio_segflg == UIO_SYSSPACE) + NFSBCOPY(mbufcp, uiocp, xfer); + else + copyout(mbufcp, uiocp, xfer); left -= xfer; + len -= xfer; + mbufcp += xfer; uiocp += xfer; uiop->uio_offset += xfer; uiop->uio_resid -= xfer; - if (left > 0 && !nfsm_shiftnext(nd, &len)) { - error = EBADRPC; - goto out; - } } if (uiop->uio_iov->iov_len <= siz) { uiop->uio_iovcnt--; @@ -679,8 +697,14 @@ nfsm_mbufuio(struct nfsrv_descript *nd, struct uio *ui } siz -= uiosiz; } - if (rem > 0) - error = nfsm_advance(nd, rem, -1); + nd->nd_dpos = mbufcp; + nd->nd_md = mp; + if (rem > 0) { + if (len < rem) + error = nfsm_advance(nd, rem, len); + else + nd->nd_dpos += rem; + } out: NFSEXITCODE2(error, nd); @@ -698,83 +722,58 @@ APPLESTATIC void * nfsm_dissct(struct nfsrv_descript *nd, int siz, int how) { struct mbuf *mp2; - struct mbuf_ext_pgs *pgs; int siz2, xfer; caddr_t p; int left; caddr_t retp; retp = NULL; - if ((nd->nd_md->m_flags & M_NOMAP) != 0) - left = nd->nd_dextpgsiz; - else - left = mtod(nd->nd_md, char *) + nd->nd_md->m_len - - nd->nd_dpos; + left = mtod(nd->nd_md, caddr_t) + nd->nd_md->m_len - nd->nd_dpos; while (left == 0) { - if ((nd->nd_md->m_flags & M_NOMAP) != 0 && - nd->nd_dextpg < - nd->nd_md->m_ext_pgs.npgs - 1) { - pgs = &nd->nd_md->m_ext_pgs; - nd->nd_dextpg++; - nd->nd_dpos = (char *)(void *) - PHYS_TO_DMAP(nd->nd_md->m_epg_pa[nd->nd_dextpg]); - left = nd->nd_dextpgsiz = mbuf_ext_pg_len(pgs, - nd->nd_dextpg, 0); - } else if (!nfsm_shiftnext(nd, &left)) - return (NULL); + nd->nd_md = nd->nd_md->m_next; + if (nd->nd_md == NULL) + return (retp); + left = nd->nd_md->m_len; + nd->nd_dpos = mtod(nd->nd_md, caddr_t); } if (left >= siz) { retp = nd->nd_dpos; nd->nd_dpos += siz; - if ((nd->nd_md->m_flags & M_NOMAP) != 0) - nd->nd_dextpgsiz -= siz; + } else if (nd->nd_md->m_next == NULL) { + return (retp); } else if (siz > ncl_mbuf_mhlen) { panic("nfs S too big"); } else { - /* Make sure an ext_pgs mbuf is at the last page. */ - if ((nd->nd_md->m_flags & M_NOMAP) != 0) { - if (nd->nd_dextpg < - nd->nd_md->m_ext_pgs.npgs - 1) { - mp2 = nfsm_splitatpgno(nd->nd_md, - nd->nd_dextpg, how); - if (mp2 == NULL) - return (NULL); - } - nd->nd_md->m_ext_pgs.last_pg_len -= left; - } - if (nd->nd_md->m_next == NULL) - return (NULL); - - /* Allocate a new mbuf for the "siz" bytes of data. */ MGET(mp2, MT_DATA, how); if (mp2 == NULL) return (NULL); - - /* - * Link the new mp2 mbuf into the list then copy left - * bytes from the mbuf before it and siz - left bytes - * from the mbuf after it. - */ mp2->m_next = nd->nd_md->m_next; nd->nd_md->m_next = mp2; nd->nd_md->m_len -= left; - retp = p = mtod(mp2, char *); - memcpy(p, nd->nd_dpos, left); /* Copy what was left */ + nd->nd_md = mp2; + retp = p = mtod(mp2, caddr_t); + NFSBCOPY(nd->nd_dpos, p, left); /* Copy what was left */ siz2 = siz - left; p += left; - mp2->m_len = siz; - nd->nd_md = mp2->m_next; + mp2 = mp2->m_next; /* Loop around copying up the siz2 bytes */ while (siz2 > 0) { - if (nd->nd_md == NULL) + if (mp2 == NULL) return (NULL); - nfsm_set(nd, 0, false); - xfer = nfsm_copyfrommbuf(nd, p, UIO_SYSSPACE, siz2); - p += xfer; - siz2 -= xfer; + xfer = (siz2 > mp2->m_len) ? mp2->m_len : siz2; + if (xfer > 0) { + NFSBCOPY(mtod(mp2, caddr_t), p, xfer); + mp2->m_data += xfer; + mp2->m_len -= xfer; + p += xfer; + siz2 -= xfer; + } if (siz2 > 0) - nd->nd_md = nd->nd_md->m_next; + mp2 = mp2->m_next; } + nd->nd_md->m_len = siz; + nd->nd_md = mp2; + nd->nd_dpos = mtod(mp2, caddr_t); } return (retp); } @@ -788,7 +787,7 @@ nfsm_dissct(struct nfsrv_descript *nd, int siz, int ho APPLESTATIC int nfsm_advance(struct nfsrv_descript *nd, int offs, int left) { - int error = 0, xfer; + int error = 0; if (offs == 0) goto out; @@ -805,39 +804,24 @@ nfsm_advance(struct nfsrv_descript *nd, int offs, int /* * If left == -1, calculate it here. */ - if (left == -1) { - if ((nd->nd_md->m_flags & M_NOMAP) != 0) - left = nd->nd_dextpgsiz; - else - left = mtod(nd->nd_md, char *) + - nd->nd_md->m_len - nd->nd_dpos; - } + if (left == -1) + left = mtod(nd->nd_md, caddr_t) + nd->nd_md->m_len - + nd->nd_dpos; /* * Loop around, advancing over the mbuf data. */ while (offs > left) { - if ((nd->nd_md->m_flags & M_NOMAP) != 0 && - nd->nd_dextpg < - nd->nd_md->m_ext_pgs.npgs - 1) { - xfer = nfsm_copyfrommbuf_extpgs(nd, NULL, - UIO_SYSSPACE, offs); - offs -= xfer; - } else - offs -= left; - left = 0; - if (offs > 0 && !nfsm_shiftnext(nd, &left)) { + offs -= left; + nd->nd_md = nd->nd_md->m_next; + if (nd->nd_md == NULL) { error = EBADRPC; goto out; } + left = nd->nd_md->m_len; + nd->nd_dpos = mtod(nd->nd_md, caddr_t); } - if (offs > 0) { - if ((nd->nd_md->m_flags & M_NOMAP) != 0) - nfsm_copyfrommbuf_extpgs(nd, NULL, - UIO_SYSSPACE, offs); - else - nd->nd_dpos += offs; - } + nd->nd_dpos += offs; out: NFSEXITCODE(error); @@ -2468,21 +2452,45 @@ nfsv4_wanted(struct nfsv4lock *lp) APPLESTATIC int nfsrv_mtostr(struct nfsrv_descript *nd, char *str, int siz) { - int rem, error = 0, xfer; + char *cp; + int xfer, len; + struct mbuf *mp; + int rem, error = 0; + mp = nd->nd_md; + cp = nd->nd_dpos; + len = mtod(mp, caddr_t) + mp->m_len - cp; rem = NFSM_RNDUP(siz) - siz; while (siz > 0) { - xfer = nfsm_copyfrommbuf(nd, str, UIO_SYSSPACE, siz); + if (len > siz) + xfer = siz; + else + xfer = len; + NFSBCOPY(cp, str, xfer); str += xfer; siz -= xfer; - if (siz > 0 && !nfsm_shiftnext(nd, &xfer)) { - error = EBADRPC; - goto out; + if (siz > 0) { + mp = mp->m_next; + if (mp == NULL) { + error = EBADRPC; + goto out; + } + cp = mtod(mp, caddr_t); + len = mp->m_len; + } else { + cp += xfer; + len -= xfer; } } *str = '\0'; - if (rem > 0) - error = nfsm_advance(nd, rem, -1); + nd->nd_dpos = cp; + nd->nd_md = mp; + if (rem > 0) { + if (len < rem) + error = nfsm_advance(nd, rem, len); + else + nd->nd_dpos += rem; + } out: NFSEXITCODE2(error, nd); @@ -4945,149 +4953,6 @@ nfsm_set(struct nfsrv_descript *nd, u_int offs, bool b } /* - * Copy up to "len" bytes from the mbuf into "cp" and adjust the - * mbuf accordingly. - * If cp == NULL, do not do the actual copy, but adjust the mbuf. - * Return the number of bytes actually copied. - * Adjust m_data and m_len so that a future calculation of what - * is left using mtod() will work correctly. - */ -static int -nfsm_copyfrommbuf(struct nfsrv_descript *nd, char *cp, enum uio_seg segflg, - int len) -{ - struct mbuf *m; - int xfer; - - m = nd->nd_md; - if ((m->m_flags & M_NOMAP) != 0) { - xfer = nfsm_copyfrommbuf_extpgs(nd, cp, segflg, len); - return (xfer); - } - xfer = mtod(m, char *) + m->m_len - nd->nd_dpos; - xfer = min(xfer, len); - if (xfer > 0) { - if (cp != NULL) { - if (segflg == UIO_SYSSPACE) - memcpy(cp, nd->nd_dpos, xfer); - else - copyout(nd->nd_dpos, cp, xfer); - } - nd->nd_dpos += xfer; - m->m_data += xfer; - m->m_len -= xfer; - } - return (xfer); -} - -/* - * Copy up to "len" bytes from the mbuf into "cp" and adjust the - * mbuf accordingly. - * If cp == NULL, do not do the actual copy, but adjust the mbuf. - * Return the number of bytes actually copied. - * Same as above, but for an ext_pgs mbuf. - */ -static int -nfsm_copyfrommbuf_extpgs(struct nfsrv_descript *nd, char *cp, - enum uio_seg segflg, int len) -{ - struct mbuf_ext_pgs *pgs; - int tlen, xfer; - - pgs = &nd->nd_md->m_ext_pgs; - tlen = 0; - /* Copy from the page(s) into cp. */ - do { - xfer = nd->nd_dextpgsiz; - xfer = min(xfer, len); - if (cp != NULL && xfer > 0) { - if (segflg == UIO_SYSSPACE) - memcpy(cp, nd->nd_dpos, xfer); - else - copyout(nd->nd_dpos, cp, xfer); - cp += xfer; - } - tlen += xfer; - len -= xfer; - nd->nd_dextpgsiz -= xfer; - nd->nd_dpos += xfer; - if (nd->nd_dextpgsiz == 0 && len > 0 && - nd->nd_dextpg < pgs->npgs - 1) { - nd->nd_dextpg++; - nd->nd_dpos = (char *)(void *) - PHYS_TO_DMAP(nd->nd_md->m_epg_pa[nd->nd_dextpg]); - nd->nd_dextpgsiz = mbuf_ext_pg_len(pgs, - nd->nd_dextpg, 0); - } - } while (len > 0 && nd->nd_dextpgsiz > 0); - return (tlen); -} - -/* - * Split an ext_pgs mbuf into two ext_pgs mbufs on a page boundary. - */ -static struct mbuf * -nfsm_splitatpgno(struct mbuf *mp, int pgno, int how) -{ - struct mbuf *m; - struct mbuf_ext_pgs *pgs, *pgs0; - int i, j, tlen; - - KASSERT((mp->m_flags & (M_EXT | M_NOMAP)) == - (M_EXT | M_NOMAP), ("nfsm_splitatpgno: mp not ext_pgs")); - pgs = &mp->m_ext_pgs; - KASSERT(pgno < pgs->npgs - 1, ("nfsm_splitatpgno:" - " at the last page")); - m = mb_alloc_ext_pgs(how, mb_free_mext_pgs); - if (m == NULL) - return (m); - pgs0 = &m->m_ext_pgs; - pgs0->flags |= MBUF_PEXT_FLAG_ANON; - - /* Move the pages beyond pgno to the new mbuf. */ - for (i = pgno + 1, j = 0; i < pgs->npgs; i++, j++) - m->m_epg_pa[j] = mp->m_epg_pa[i]; - pgs0->npgs = j; - pgs0->last_pg_len = pgs->last_pg_len; - pgs->npgs = pgno + 1; - pgs->last_pg_len = PAGE_SIZE; - if (pgno == 0) - pgs->last_pg_len -= pgs->first_pg_off; - - /* Now set m_len for both mbufs. */ - tlen = mbuf_ext_pg_len(pgs, 0, pgs->first_pg_off); - for (i = 1; i < pgs->npgs; i++) - tlen += mbuf_ext_pg_len(pgs, i, 0); - mp->m_len = tlen; - - /* The new mbuf has first_pg_off == 0. */ - tlen = 0; - for (i = 0; i < pgs0->npgs; i++) - tlen += mbuf_ext_pg_len(pgs0, i, 0); - m->m_len = tlen; - - /* Link the new mbuf after mp. */ - m->m_next = mp->m_next; - mp->m_next = m; - return (mp); -} - -/* - * Shift to the next mbuf in the list list and update the nd fields. - * Return true if successful, false otherwise. - */ -bool -nfsm_shiftnext(struct nfsrv_descript *nd, int *leftp) -{ - - nd->nd_md = nd->nd_md->m_next; - if (nd->nd_md == NULL) - return (false); - *leftp = nfsm_set(nd, 0, false); - return (true); -} - -/* * Grow a ext_pgs mbuf list. Either allocate another page or add * an mbuf to the list. */ @@ -5119,31 +4984,4 @@ nfsm_add_ext_pgs(struct mbuf *m, int maxextsiz, int *b mp = m; } return (mp); -} - -/* - * Calculate the data offset of m for dextpg and dextpgsiz. - */ -int -nfsm_extpgs_calc_offs(struct mbuf *m, int dextpg, int dextpgsiz) -{ - struct mbuf_ext_pgs *pgs; - int cnt, offs; - - offs = 0; - pgs = &m->m_ext_pgs; - for (cnt = 0; cnt < dextpg; cnt++) { - if (cnt == 0) - offs += mbuf_ext_pg_len(pgs, 0, - pgs->first_pg_off); - else - offs += mbuf_ext_pg_len(pgs, cnt, 0); - } - if (dextpg == 0) - cnt = mbuf_ext_pg_len(pgs, 0, - pgs->first_pg_off); - else - cnt = mbuf_ext_pg_len(pgs, dextpg, 0); - offs += cnt - dextpgsiz; - return (offs); } Modified: projects/nfs-over-tls/sys/fs/nfs/nfs_var.h ============================================================================== --- projects/nfs-over-tls/sys/fs/nfs/nfs_var.h Sun May 10 20:28:38 2020 (r360882) +++ projects/nfs-over-tls/sys/fs/nfs/nfs_var.h Sun May 10 20:44:43 2020 (r360883) @@ -362,8 +362,6 @@ void nfsv4_freeslot(struct nfsclsession *, int); struct ucred *nfsrv_getgrpscred(struct ucred *); struct nfsdevice *nfsv4_findmirror(struct nfsmount *); int nfsm_set(struct nfsrv_descript *, u_int, bool); -bool nfsm_shiftnext(struct nfsrv_descript *, int *); -int nfsm_extpgs_calc_offs(struct mbuf *, int, int); /* nfs_clcomsubs.c */ void nfsm_uiombuf(struct nfsrv_descript *, struct uio *, int); @@ -686,8 +684,8 @@ int nfsvno_readlink(vnode_t, struct ucred *, int, NFSP struct mbuf **, int *); int nfsvno_read(vnode_t, off_t, int, struct ucred *, int, NFSPROC_T *, struct mbuf **, struct mbuf **); -int nfsvno_write(vnode_t, off_t, int, int *, struct nfsrv_descript *, - NFSPROC_T *); +int nfsvno_write(vnode_t, off_t, int, int *, struct mbuf *, char *, + struct ucred *, NFSPROC_T *); int nfsvno_createsub(struct nfsrv_descript *, struct nameidata *, vnode_t *, struct nfsvattr *, int *, int32_t *, NFSDEV_T, struct nfsexstuff *); Modified: projects/nfs-over-tls/sys/fs/nfs/nfsm_subs.h ============================================================================== --- projects/nfs-over-tls/sys/fs/nfs/nfsm_subs.h Sun May 10 20:28:38 2020 (r360882) +++ projects/nfs-over-tls/sys/fs/nfs/nfsm_subs.h Sun May 10 20:44:43 2020 (r360883) @@ -57,11 +57,6 @@ * Replace most of the macro with an inline function, to minimize * the machine code. The inline functions in lower case can be called * directly, bypassing the macro. - * For ND_NOMAP, if there is not enough contiguous space left in - * the mbuf page, allocate a regular mbuf. The data in these regular - * mbufs will need to be copied into pages later, since the data must - * be filled pages. This should only happen after a write request or - * read reply has been filled into the mbuf list. */ static __inline void * nfsm_build(struct nfsrv_descript *nd, int siz) @@ -106,22 +101,12 @@ nfsm_dissect(struct nfsrv_descript *nd, int siz) int tt1; void *retp; - if ((nd->nd_md->m_flags & (M_EXT | M_NOMAP)) == - (M_EXT | M_NOMAP)) { - if (nd->nd_dextpgsiz >= siz) { - retp = (void *)nd->nd_dpos; - nd->nd_dpos += siz; - nd->nd_dextpgsiz -= siz; - } else - retp = nfsm_dissct(nd, siz, M_WAITOK); - } else { - tt1 = mtod(nd->nd_md, char *) + nd->nd_md->m_len - - nd->nd_dpos; - if (tt1 >= siz) { - retp = (void *)nd->nd_dpos; - nd->nd_dpos += siz; - } else - retp = nfsm_dissct(nd, siz, M_WAITOK); + tt1 = mtod(nd->nd_md, caddr_t) + nd->nd_md->m_len - nd->nd_dpos; + if (tt1 >= siz) { + retp = (void *)nd->nd_dpos; + nd->nd_dpos += siz; + } else { + retp = nfsm_dissct(nd, siz, M_WAITOK); } return (retp); } @@ -132,22 +117,12 @@ nfsm_dissect_nonblock(struct nfsrv_descript *nd, int s int tt1; void *retp; - if ((nd->nd_md->m_flags & (M_EXT | M_NOMAP)) == - (M_EXT | M_NOMAP)) { - if (nd->nd_dextpgsiz >= siz) { - retp = (void *)nd->nd_dpos; - nd->nd_dpos += siz; - nd->nd_dextpgsiz -= siz; - } else - retp = nfsm_dissct(nd, siz, M_NOWAIT); - } else { - tt1 = mtod(nd->nd_md, char *) + nd->nd_md->m_len - - nd->nd_dpos; - if (tt1 >= siz) { - retp = (void *)nd->nd_dpos; - nd->nd_dpos += siz; - } else - retp = nfsm_dissct(nd, siz, M_NOWAIT); + tt1 = mtod(nd->nd_md, caddr_t) + nd->nd_md->m_len - nd->nd_dpos; + if (tt1 >= siz) { + retp = (void *)nd->nd_dpos; + nd->nd_dpos += siz; + } else { + retp = nfsm_dissct(nd, siz, M_NOWAIT); } return (retp); } Modified: projects/nfs-over-tls/sys/fs/nfsserver/nfs_nfsdport.c ============================================================================== --- projects/nfs-over-tls/sys/fs/nfsserver/nfs_nfsdport.c Sun May 10 20:28:38 2020 (r360882) +++ projects/nfs-over-tls/sys/fs/nfsserver/nfs_nfsdport.c Sun May 10 20:44:43 2020 (r360883) @@ -123,14 +123,14 @@ static void nfsrv_pnfsremovesetup(struct vnode *, NFSP static void nfsrv_pnfsremove(struct vnode **, int, char *, fhandle_t *, NFSPROC_T *); static int nfsrv_proxyds(struct vnode *, off_t, int, struct ucred *, - struct thread *, int, struct mbuf **, struct nfsrv_descript *, + struct thread *, int, struct mbuf **, char *, struct mbuf **, struct nfsvattr *, struct acl *, off_t *, int, bool *); static int nfsrv_setextattr(struct vnode *, struct nfsvattr *, NFSPROC_T *); static int nfsrv_readdsrpc(fhandle_t *, off_t, int, struct ucred *, NFSPROC_T *, struct nfsmount *, struct mbuf **, struct mbuf **); static int nfsrv_writedsrpc(fhandle_t *, off_t, int, struct ucred *, NFSPROC_T *, struct vnode *, struct nfsmount **, int, struct mbuf **, - struct nfsrv_descript *, int *); + char *, int *); static int nfsrv_allocatedsrpc(fhandle_t *, off_t, off_t, struct ucred *, NFSPROC_T *, struct vnode *, struct nfsmount **, int, int *); static int nfsrv_setacldsrpc(fhandle_t *, struct ucred *, NFSPROC_T *, @@ -1122,7 +1122,7 @@ nfsrv_createiovecw_extpgs(int retlen, struct mbuf *m, */ int nfsvno_write(struct vnode *vp, off_t off, int retlen, int *stable, - struct nfsrv_descript *nd, struct thread *p) + struct mbuf *mp, char *cp, struct ucred *cred, struct thread *p) { struct iovec *iv; int cnt, ioflags, error; @@ -1133,25 +1133,19 @@ nfsvno_write(struct vnode *vp, off_t off, int retlen, * Attempt to write to a DS file. A return of ENOENT implies * there is no DS file to write. */ - error = nfsrv_proxyds(vp, off, retlen, nd->nd_cred, p, - NFSPROC_WRITEDS, &nd->nd_md, nd, NULL, NULL, NULL, - NULL, 0, NULL); + error = nfsrv_proxyds(vp, off, retlen, cred, p, NFSPROC_WRITEDS, + &mp, cp, NULL, NULL, NULL, NULL, 0, NULL); if (error != ENOENT) { *stable = NFSWRITE_FILESYNC; return (error); } + if (*stable == NFSWRITE_UNSTABLE) ioflags = IO_NODELOCKED; else ioflags = (IO_SYNC | IO_NODELOCKED); - if ((nd->nd_md->m_flags & M_NOMAP) != 0) - error = nfsrv_createiovecw_extpgs(retlen, nd->nd_md, - nd->nd_dpos, nd->nd_dextpg, nd->nd_dextpgsiz, - &iv, &cnt); - else - error = nfsrv_createiovecw(retlen, nd->nd_md, - nd->nd_dpos, &iv, &cnt); + error = nfsrv_createiovecw(retlen, mp, cp, &iv, &cnt); if (error != 0) return (error); uiop->uio_iov = iv; @@ -1165,7 +1159,7 @@ nfsvno_write(struct vnode *vp, off_t off, int retlen, ioflags |= nh->nh_seqcount << IO_SEQSHIFT; /* XXX KDM make this more systematic? */ nfsstatsv1.srvbytes[NFSV4OP_WRITE] += uiop->uio_resid; - error = VOP_WRITE(vp, uiop, ioflags, nd->nd_cred); + error = VOP_WRITE(vp, uiop, ioflags, cred); if (error == 0) nh->nh_nextoff = uiop->uio_offset; free(iv, M_TEMP); @@ -4670,7 +4664,7 @@ nfsrv_dssetacl(struct vnode *vp, struct acl *aclp, str static int nfsrv_proxyds(struct vnode *vp, off_t off, int cnt, struct ucred *cred, - struct thread *p, int ioproc, struct mbuf **mpp, struct nfsrv_descript *nd, + struct thread *p, int ioproc, struct mbuf **mpp, char *cp, struct mbuf **mpp2, struct nfsvattr *nap, struct acl *aclp, off_t *offp, int content, bool *eofp) { @@ -4802,7 +4796,7 @@ tryagain: } } else if (ioproc == NFSPROC_WRITEDS) error = nfsrv_writedsrpc(fh, off, cnt, cred, p, vp, - &nmp[0], mirrorcnt, mpp, nd, &failpos); + &nmp[0], mirrorcnt, mpp, cp, &failpos); else if (ioproc == NFSPROC_SETATTR) error = nfsrv_setattrdsrpc(fh, cred, p, vp, &nmp[0], mirrorcnt, nap, &failpos); @@ -5180,54 +5174,37 @@ nfsrv_readdsrpc(fhandle_t *fhp, off_t off, int len, st } /* - * Now, get rid of mbuf data that preceeds the - * current position. For a regular mbuf, adjust - * m_data, m_len and then find the end of the read - * data and trim off any mbuf(s) after that. - * For an ext_pgs mbuf, split it and free the first - * and third mbuf chains. + * Now, adjust first mbuf so that any XDR before the + * read data is skipped over. */ + trimlen = nd->nd_dpos - mtod(m, char *); + if (trimlen > 0) { + m->m_len -= trimlen; + NFSM_DATAP(m, trimlen); + } + + /* + * Truncate the mbuf chain at retlen bytes of data, + * plus XDR padding that brings the length up to a + * multiple of 4. + */ tlen = NFSM_RNDUP(retlen); - if ((m->m_flags & M_NOMAP) != 0) { - trimlen = nfsm_extpgs_calc_offs(m, - nd->nd_dextpg, nd->nd_dextpgsiz); - nd->nd_mrep = mb_splitatpos_ext(m, trimlen, - M_WAITOK); - m_freem(m); - m = mb_splitatpos_ext(nd->nd_mrep, tlen, - M_WAITOK); - m_freem(m); - m = m_last(nd->nd_mrep); - } else { - trimlen = nd->nd_dpos - mtod(m, char *); - if (trimlen > 0) { - m->m_len -= trimlen; - m->m_data += trimlen; + do { + if (m->m_len >= tlen) { + m->m_len = tlen; + tlen = 0; + m2 = m->m_next; + m->m_next = NULL; + m_freem(m2); + break; } - - /* - * Truncate the mbuf chain at retlen bytes of - * data, plus XDR padding that brings the - * length up to a multiple of 4. - */ - do { - if (m->m_len >= tlen) { - m->m_len = tlen; - tlen = 0; - m2 = m->m_next; - m->m_next = NULL; - m_freem(m2); - break; - } - tlen -= m->m_len; - m = m->m_next; - } while (m != NULL); - if (tlen > 0) { - printf("nfsrv_readdsrpc: busted mbuf " - "list\n"); - error = ENOENT; - goto nfsmout; - } + tlen -= m->m_len; + m = m->m_next; + } while (m != NULL); + if (tlen > 0) { + printf("nfsrv_readdsrpc: busted mbuf list\n"); + error = ENOENT; + goto nfsmout; } *mpp = nd->nd_mrep; *mpendp = m; @@ -5391,13 +5368,12 @@ start_writedsdorpc(void *arg, int pending) static int nfsrv_writedsrpc(fhandle_t *fhp, off_t off, int len, struct ucred *cred, NFSPROC_T *p, struct vnode *vp, struct nfsmount **nmpp, int mirrorcnt, - struct mbuf **mpp, struct nfsrv_descript *nd, int *failposp) + struct mbuf **mpp, char *cp, int *failposp) { struct nfsrvwritedsdorpc *drpc, *tdrpc = NULL; struct nfsvattr na; - struct mbuf *m, *m1, *m2; + struct mbuf *m; int error, i, offs, ret, timo; - bool gotnomap; NFSD_DEBUG(4, "in nfsrv_writedsrpc\n"); KASSERT(*mpp != NULL, ("nfsrv_writedsrpc: NULL mbuf chain")); @@ -5406,27 +5382,11 @@ nfsrv_writedsrpc(fhandle_t *fhp, off_t off, int len, s tdrpc = drpc = malloc(sizeof(*drpc) * (mirrorcnt - 1), M_TEMP, M_WAITOK); - NFSD_DEBUG(4, "nfsrv_writedsrpc: mcopy len=%d\n", len); + /* Calculate offset in mbuf chain that data starts. */ + offs = cp - mtod(*mpp, char *); + NFSD_DEBUG(4, "nfsrv_writedsrpc: mcopy offs=%d len=%d\n", offs, len); /* - * For M_NOMAP mbufs, the mbuf chain needs to be split into 3 chains - * so that m_copym() can be done with offs == 0 and M_COPYALL. - * *mpp - Everything that preceeds the data to be written. - * m1 - The data to be written. - * m2 - Everything that follows the data to be written. - */ - m1 = *mpp; - gotnomap = false; - if ((m1->m_flags & M_NOMAP) != 0) { - gotnomap = true; - offs = nfsm_extpgs_calc_offs(nd->nd_md, nd->nd_dextpg, - nd->nd_dextpgsiz); - m1 = mb_splitatpos_ext(m1, offs, M_WAITOK); - m2 = mb_splitatpos_ext(m1, NFSM_RNDUP(len), M_WAITOK); - } else - offs = nd->nd_dpos - mtod(m1, char *); - - /* * Do the write RPC for every DS, using a separate kernel process * for every DS except the last one. */ @@ -5441,11 +5401,7 @@ nfsrv_writedsrpc(fhandle_t *fhp, off_t off, int len, s tdrpc->p = p; tdrpc->inprog = 0; tdrpc->err = 0; - if (gotnomap) - tdrpc->m = m_copym(m1, 0, M_COPYALL, M_WAITOK); - else - tdrpc->m = m_copym(m1, offs, NFSM_RNDUP(len), - M_WAITOK); + tdrpc->m = m_copym(*mpp, offs, NFSM_RNDUP(len), M_WAITOK); ret = EIO; if (nfs_pnfsiothreads != 0) { ret = nfs_pnfsio(start_writedsdorpc, tdrpc); @@ -5463,10 +5419,7 @@ nfsrv_writedsrpc(fhandle_t *fhp, off_t off, int len, s nmpp++; fhp++; } - if (gotnomap) - m = m_copym(m1, 0, M_COPYALL, M_WAITOK); - else - m = m_copym(m1, offs, NFSM_RNDUP(len), M_WAITOK); + m = m_copym(*mpp, offs, NFSM_RNDUP(len), M_WAITOK); ret = nfsrv_writedsdorpc(*nmpp, fhp, off, len, &na, m, cred, p); if (nfsds_failerr(ret) && *failposp == -1 && mirrorcnt > 1) *failposp = mirrorcnt - 1; @@ -5487,14 +5440,6 @@ nfsrv_writedsrpc(fhandle_t *fhp, off_t off, int len, s *failposp = i; else if (error == 0 && tdrpc->err != 0) error = tdrpc->err; - } - - /* For gotnomap, chain the lists back to-gether. */ - if (gotnomap) { - m_last(*mpp)->m_next = m1; - m_last(m1)->m_next = m2; - nd->nd_md = m1; - nfsm_set(nd, 0, false); } free(drpc, M_TEMP); return (error); Modified: projects/nfs-over-tls/sys/fs/nfsserver/nfs_nfsdserv.c ============================================================================== --- projects/nfs-over-tls/sys/fs/nfsserver/nfs_nfsdserv.c Sun May 10 20:28:38 2020 (r360882) +++ projects/nfs-over-tls/sys/fs/nfsserver/nfs_nfsdserv.c Sun May 10 20:44:43 2020 (r360883) @@ -1059,8 +1059,8 @@ nfsrvd_write(struct nfsrv_descript *nd, __unused int i * which is to return ok so long as there are no permission problems. */ if (retlen > 0) { - nd->nd_repstat = nfsvno_write(vp, off, retlen, &stable, nd, - p); + nd->nd_repstat = nfsvno_write(vp, off, retlen, &stable, + nd->nd_md, nd->nd_dpos, nd->nd_cred, p); error = nfsm_advance(nd, NFSM_RNDUP(retlen), -1); if (error) goto nfsmout; Modified: projects/nfs-over-tls/sys/fs/nfsserver/nfs_nfsdsubs.c ============================================================================== --- projects/nfs-over-tls/sys/fs/nfsserver/nfs_nfsdsubs.c Sun May 10 20:28:38 2020 (r360882) +++ projects/nfs-over-tls/sys/fs/nfsserver/nfs_nfsdsubs.c Sun May 10 20:44:43 2020 (r360883) @@ -1870,9 +1870,8 @@ APPLESTATIC int nfsrv_parsename(struct nfsrv_descript *nd, char *bufp, u_long *hashp, NFSPATHLEN_T *outlenp) { - struct mbuf_ext_pgs *pgs; - vm_page_t pg; char *fromcp, *tocp, val = '\0'; + struct mbuf *md; int i; int rem, len, error = 0, pubtype = 0, outlen = 0, percent = 0; char digit; @@ -1887,196 +1886,177 @@ nfsrv_parsename(struct nfsrv_descript *nd, char *bufp, * Otherwise, get the component name. */ if ((nd->nd_flag & ND_NFSV4) && nd->nd_procnum == NFSV4OP_LOOKUPP) { - *tocp++ = '.'; - hash += ((u_char)'.'); - *tocp++ = '.'; - hash += ((u_char)'.'); - outlen = 2; + *tocp++ = '.'; + hash += ((u_char)'.'); + *tocp++ = '.'; + hash += ((u_char)'.'); + outlen = 2; } else { - /* - * First, get the name length. - */ - NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); - len = fxdr_unsigned(int, *tl); - if (len > NFS_MAXNAMLEN) { - nd->nd_repstat = NFSERR_NAMETOL; + /* + * First, get the name length. + */ + NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); + len = fxdr_unsigned(int, *tl); + if (len > NFS_MAXNAMLEN) { + nd->nd_repstat = NFSERR_NAMETOL; + error = 0; + goto nfsmout; + } else if (len <= 0) { + nd->nd_repstat = NFSERR_INVAL; + error = 0; + goto nfsmout; + } + + /* + * Now, copy the component name into the buffer. + */ + fromcp = nd->nd_dpos; + md = nd->nd_md; + rem = mtod(md, caddr_t) + md->m_len - fromcp; + for (i = 0; i < len; i++) { + while (rem == 0) { + md = md->m_next; + if (md == NULL) { + error = EBADRPC; + goto nfsmout; + } + fromcp = mtod(md, caddr_t); + rem = md->m_len; + } + if (*fromcp == '\0') { + nd->nd_repstat = EACCES; error = 0; goto nfsmout; - } else if (len <= 0) { - nd->nd_repstat = NFSERR_INVAL; - error = 0; - goto nfsmout; } - /* - * Now, copy the component name into the buffer. + * For lookups on the public filehandle, do some special + * processing on the name. (The public file handle is the + * root of the public file system for this server.) */ - fromcp = nd->nd_dpos; - if ((nd->nd_md->m_flags & M_NOMAP) != 0) - rem = nd->nd_dextpgsiz; - else - rem = mtod(nd->nd_md, char *) + nd->nd_md->m_len - - fromcp; - for (i = 0; i < len; i++) { - while (rem == 0) { - if ((nd->nd_md->m_flags & M_NOMAP) != 0 && - nd->nd_dextpg < - nd->nd_md->m_ext_pgs.npgs - 1) { - pgs = &nd->nd_md->m_ext_pgs; - pg = PHYS_TO_VM_PAGE( - nd->nd_md->m_epg_pa[nd->nd_dextpg]); - vm_page_unwire_noq(pg); - vm_page_free(pg); - for (i = nd->nd_bextpg; - i < pgs->npgs - 1; i++) - nd->nd_md->m_epg_pa[i] = - nd->nd_md->m_epg_pa[i + 1]; - pgs->npgs--; - if (nd->nd_dextpg == 0) - pgs->first_pg_off = 0; - fromcp = nd->nd_dpos = (char *)(void *) - PHYS_TO_DMAP( - nd->nd_md->m_epg_pa[nd->nd_dextpg]); - rem = nd->nd_dextpgsiz = - mbuf_ext_pg_len(pgs, nd->nd_dextpg, - 0); + if (nd->nd_flag & ND_PUBLOOKUP) { + /* + * If the first char is ASCII, it is a canonical + * path, otherwise it is a native path. (RFC2054 + * doesn't actually state what it is if the first + * char isn't ASCII or 0x80, so I assume native.) + * pubtype == 1 -> native path + * pubtype == 2 -> canonical path + */ + if (i == 0) { + if (*fromcp & 0x80) { + /* + * Since RFC2054 doesn't indicate + * that a native path of just 0x80 + * isn't allowed, I'll replace the + * 0x80 with '/' instead of just + * throwing it away. + */ + *fromcp = '/'; + pubtype = 1; } else { - if (!nfsm_shiftnext(nd, &rem)) { - error = EBADRPC; - goto nfsmout; - } - fromcp = nd->nd_dpos; + pubtype = 2; } } - if (*fromcp == '\0') { + /* + * '/' only allowed in a native path + */ + if (*fromcp == '/' && pubtype != 1) { nd->nd_repstat = EACCES; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202005102044.04AKiiC5019215>