svn commit: r360883 - in projects/nfs-over-tls/sys/fs: nfs nfsserver
Rick Macklem
rmacklem at FreeBSD.org
Sun May 10 20:44:45 UTC 2020
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 ***
More information about the svn-src-projects
mailing list