svn commit: r358770 - projects/nfs-over-tls/sys/fs/nfs
Rick Macklem
rmacklem at FreeBSD.org
Sun Mar 8 19:02:31 UTC 2020
Author: rmacklem
Date: Sun Mar 8 19:02:30 2020
New Revision: 358770
URL: https://svnweb.freebsd.org/changeset/base/358770
Log:
Add support for reception of ext_pgs mbuf chains to the common NFS code.
Also, simplify the check for ext_pgs mbufs to just test for M_NOMAP.
Get rid of a couple of functions that are no longer needed.
And fix newnfs_realign() so that it works for ext_pgs mbufs.
Modified:
projects/nfs-over-tls/sys/fs/nfs/nfs_commonkrpc.c
projects/nfs-over-tls/sys/fs/nfs/nfs_commonport.c
projects/nfs-over-tls/sys/fs/nfs/nfs_commonsubs.c
projects/nfs-over-tls/sys/fs/nfs/nfs_var.h
Modified: projects/nfs-over-tls/sys/fs/nfs/nfs_commonkrpc.c
==============================================================================
--- projects/nfs-over-tls/sys/fs/nfs/nfs_commonkrpc.c Sun Mar 8 18:54:59 2020 (r358769)
+++ projects/nfs-over-tls/sys/fs/nfs/nfs_commonkrpc.c Sun Mar 8 19:02:30 2020 (r358770)
@@ -898,11 +898,9 @@ tryagain:
* These could cause pointer alignment problems, so copy them to
* well aligned mbufs.
*/
-#ifdef notnow
newnfs_realign(&nd->nd_mrep, M_WAITOK);
-#endif
nd->nd_md = nd->nd_mrep;
- nfsm_set(nd, false);
+ nfsm_set(nd, ext.rc_mbufoffs, false);
nd->nd_repstat = 0;
if (nd->nd_procnum != NFSPROC_NULL &&
nd->nd_procnum != NFSV4PROC_CBNULL) {
Modified: projects/nfs-over-tls/sys/fs/nfs/nfs_commonport.c
==============================================================================
--- projects/nfs-over-tls/sys/fs/nfs/nfs_commonport.c Sun Mar 8 18:54:59 2020 (r358769)
+++ projects/nfs-over-tls/sys/fs/nfs/nfs_commonport.c Sun Mar 8 19:02:30 2020 (r358770)
@@ -180,8 +180,34 @@ newnfs_realign(struct mbuf **pm, int how)
{
struct mbuf *m, *n;
int off, space;
+ bool copyit;
++nfs_realign_test;
+
+ /*
+ * For ext_pgs mbufs, just copy the entire chain if there is an
+ * alignment problem.
+ */
+ copyit = false;
+ m = *pm;
+ while ((m->m_flags & M_NOMAP) != 0) {
+ if ((m->m_len & 0x3) != 0 ||
+ (m->m_ext.ext_pgs->first_pg_off & 0x3) != 0) {
+ copyit = true;
+ break;
+ }
+ m = m->m_next;
+ if (m == NULL)
+ return (0);
+ }
+ if (copyit) {
+ m = mb_unmapped_to_ext(*pm);
+ if (m == NULL)
+ return (ENOMEM);
+ *pm = m;
+ return (0);
+ }
+
while ((m = *pm) != NULL) {
if ((m->m_len & 0x3) || (mtod(m, intptr_t) & 0x3)) {
/*
Modified: projects/nfs-over-tls/sys/fs/nfs/nfs_commonsubs.c
==============================================================================
--- projects/nfs-over-tls/sys/fs/nfs/nfs_commonsubs.c Sun Mar 8 18:54:59 2020 (r358769)
+++ projects/nfs-over-tls/sys/fs/nfs/nfs_commonsubs.c Sun Mar 8 19:02:30 2020 (r358770)
@@ -383,7 +383,7 @@ nfscl_reqstart(struct nfsrv_descript *nd, int procnum,
mb = mb_alloc_ext_plus_pages(PAGE_SIZE, M_WAITOK, false,
mb_free_mext_pgs);
nd->nd_mreq = nd->nd_mb = mb;
- nfsm_set(nd, true);
+ nfsm_set(nd, 0, true);
} else {
if (nfs_bigrequest[procnum])
NFSMCLGET(mb, M_WAITOK);
@@ -656,8 +656,7 @@ nfsm_mbufuio(struct nfsrv_descript *nd, struct uio *ui
left = siz;
uiosiz = left;
while (left > 0) {
- if ((nd->nd_md->m_flags & (M_EXT | M_NOMAP)) ==
- (M_EXT | M_NOMAP))
+ if ((nd->nd_md->m_flags & M_NOMAP) != 0)
xfer = nfsm_copyfrommbuf_extpgs(nd, uiocp,
uiop->uio_segflg, left);
else
@@ -708,15 +707,14 @@ nfsm_dissct(struct nfsrv_descript *nd, int siz, int ho
caddr_t retp;
retp = NULL;
- if ((nd->nd_md->m_flags & (M_EXT | M_NOMAP)) ==
- (M_EXT | M_NOMAP))
+ 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;
while (left == 0) {
- if ((nd->nd_md->m_flags & (M_EXT | M_NOMAP)) ==
- (M_EXT | M_NOMAP) && nd->nd_dextpg <
+ if ((nd->nd_md->m_flags & M_NOMAP) != 0 &&
+ nd->nd_dextpg <
nd->nd_md->m_ext.ext_pgs->npgs - 1) {
pgs = nd->nd_md->m_ext.ext_pgs;
nd->nd_dextpg++;
@@ -730,15 +728,13 @@ nfsm_dissct(struct nfsrv_descript *nd, int siz, int ho
if (left >= siz) {
retp = nd->nd_dpos;
nd->nd_dpos += siz;
- if ((nd->nd_md->m_flags & (M_EXT | M_NOMAP)) ==
- (M_EXT | M_NOMAP))
+ if ((nd->nd_md->m_flags & M_NOMAP) != 0)
nd->nd_dextpgsiz -= siz;
} 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_EXT | M_NOMAP)) ==
- (M_EXT | M_NOMAP)) {
+ if ((nd->nd_md->m_flags & M_NOMAP) != 0) {
if (nd->nd_dextpg <
nd->nd_md->m_ext.ext_pgs->npgs - 1) {
mp2 = nfsm_splitatpgno(nd->nd_md,
@@ -775,9 +771,8 @@ nfsm_dissct(struct nfsrv_descript *nd, int siz, int ho
while (siz2 > 0) {
if (nd->nd_md == NULL)
return (NULL);
- nfsm_set(nd, false);
- if ((nd->nd_md->m_flags & (M_EXT | M_NOMAP)) ==
- (M_EXT | M_NOMAP))
+ nfsm_set(nd, 0, false);
+ if ((nd->nd_md->m_flags & M_NOMAP) != 0)
xfer = nfsm_copyfrommbuf_extpgs(nd, p,
UIO_SYSSPACE, siz2);
else
@@ -819,8 +814,7 @@ 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_EXT | M_NOMAP)) ==
- (M_EXT | M_NOMAP))
+ if ((nd->nd_md->m_flags & M_NOMAP) != 0)
left = nd->nd_dextpgsiz;
else
left = mtod(nd->nd_md, char *) +
@@ -831,8 +825,8 @@ nfsm_advance(struct nfsrv_descript *nd, int offs, int
* Loop around, advancing over the mbuf data.
*/
while (offs > left) {
- if ((nd->nd_md->m_flags & (M_EXT | M_NOMAP)) ==
- (M_EXT | M_NOMAP) && nd->nd_dextpg <
+ if ((nd->nd_md->m_flags & M_NOMAP) != 0 &&
+ nd->nd_dextpg <
nd->nd_md->m_ext.ext_pgs->npgs - 1) {
xfer = nfsm_copyfrommbuf_extpgs(nd, NULL,
UIO_SYSSPACE, offs);
@@ -846,8 +840,7 @@ nfsm_advance(struct nfsrv_descript *nd, int offs, int
}
}
if (offs > 0) {
- if ((nd->nd_md->m_flags & (M_EXT | M_NOMAP)) ==
- (M_EXT | M_NOMAP))
+ if ((nd->nd_md->m_flags & M_NOMAP) != 0)
nfsm_copyfrommbuf_extpgs(nd, NULL,
UIO_SYSSPACE, offs);
else
@@ -1104,13 +1097,12 @@ nfsm_trimtrailing(struct nfsrv_descript *nd, struct mb
struct mbuf_ext_pgs *pgs;
vm_page_t pg;
int fullpgsiz, i;
- char *ppos;
if (mb->m_next != NULL) {
m_freem(mb->m_next);
mb->m_next = NULL;
}
- if ((mb->m_flags & (M_EXT | M_NOMAP)) == (M_EXT | M_NOMAP)) {
+ if ((mb->m_flags & M_NOMAP) != 0) {
pgs = mb->m_ext.ext_pgs;
/* First, get rid of any pages after this position. */
for (i = pgs->npgs - 1; i > bextpg; i--) {
@@ -1127,10 +1119,6 @@ nfsm_trimtrailing(struct nfsrv_descript *nd, struct mb
mb->m_len = mbuf_ext_pg_len(pgs, 0, pgs->first_pg_off);
for (i = 1; i < pgs->npgs; i++)
mb->m_len += mbuf_ext_pg_len(pgs, i, 0);
- ppos = (char *)(void *)PHYS_TO_DMAP(pgs->pa[bextpg]);
- ppos += pgs->last_pg_len;
- if (ppos != bpos)
- printf("EEK trimtrail\n");
nd->nd_bextpgsiz = bextpgsiz;
nd->nd_bextpg = bextpg;
} else
@@ -2492,8 +2480,7 @@ nfsrv_mtostr(struct nfsrv_descript *nd, char *str, int
rem = NFSM_RNDUP(siz) - siz;
while (siz > 0) {
- if ((nd->nd_md->m_flags & (M_EXT | M_NOMAP)) ==
- (M_EXT | M_NOMAP))
+ if ((nd->nd_md->m_flags & M_NOMAP) != 0)
xfer = nfsm_copyfrommbuf_extpgs(nd, str,
UIO_SYSSPACE, siz);
else
@@ -4892,7 +4879,7 @@ nfsv4_findmirror(struct nfsmount *nmp)
* The build argument is true for build and false for dissect.
*/
int
-nfsm_set(struct nfsrv_descript *nd, bool build)
+nfsm_set(struct nfsrv_descript *nd, u_int offs, bool build)
{
struct mbuf *m;
struct mbuf_ext_pgs *pgs;
@@ -4902,29 +4889,68 @@ nfsm_set(struct nfsrv_descript *nd, bool build)
m = nd->nd_mb;
else
m = nd->nd_md;
- if ((m->m_flags & (M_EXT | M_NOMAP)) == (M_EXT | M_NOMAP)) {
+ if ((m->m_flags & M_NOMAP) != 0) {
if (build) {
pgs = m->m_ext.ext_pgs;
- nd->nd_bpos = (char *)(void *)
- PHYS_TO_DMAP(pgs->pa[0]);
- nd->nd_bpos += pgs->first_pg_off;
nd->nd_bextpg = 0;
- /* For build, set the size that can be filled. */
- rlen = nd->nd_bextpgsiz = PAGE_SIZE -
- pgs->first_pg_off;
+ while (offs > 0) {
+ if (nd->nd_bextpg == 0)
+ rlen = mbuf_ext_pg_len(pgs, 0,
+ pgs->first_pg_off);
+ else
+ rlen = mbuf_ext_pg_len(pgs,
+ nd->nd_bextpg, 0);
+ if (offs <= rlen)
+ break;
+ offs -= rlen;
+ nd->nd_bextpg++;
+ if (nd->nd_bextpg == pgs->npgs) {
+ printf("nfsm_set: build offs "
+ "out of range\n");
+ nd->nd_bextpg--;
+ break;
+ }
+ }
+ nd->nd_bpos = (char *)(void *)
+ PHYS_TO_DMAP(pgs->pa[nd->nd_bextpg]);
+ if (nd->nd_bextpg == 0)
+ nd->nd_bpos += pgs->first_pg_off;
+ if (offs > 0) {
+ nd->nd_bpos += offs;
+ rlen = nd->nd_bextpgsiz = rlen - offs;
+ } else if (nd->nd_bextpg == 0)
+ rlen = nd->nd_bextpgsiz = PAGE_SIZE -
+ pgs->first_pg_off;
+ else
+ rlen = nd->nd_bextpgsiz = PAGE_SIZE;
} else {
pgs = m->m_ext.ext_pgs;
- nd->nd_dpos = (char *)(void *)
- PHYS_TO_DMAP(pgs->pa[0]);
- nd->nd_dpos += pgs->first_pg_off;
nd->nd_dextpg = 0;
- /* For dissect, set the size already filled. */
- rlen = nd->nd_dextpgsiz = mbuf_ext_pg_len(pgs, 0,
- pgs->first_pg_off);
+ do {
+ nd->nd_dpos = (char *)(void *)
+ PHYS_TO_DMAP(pgs->pa[nd->nd_dextpg]);
+ if (nd->nd_dextpg == 0) {
+ nd->nd_dpos += pgs->first_pg_off;
+ rlen = nd->nd_dextpgsiz =
+ mbuf_ext_pg_len(pgs, 0,
+ pgs->first_pg_off);
+ } else
+ rlen = nd->nd_dextpgsiz =
+ mbuf_ext_pg_len(pgs,
+ nd->nd_dextpg, 0);
+ if (offs > rlen) {
+ nd->nd_dextpg++;
+ offs -= rlen;
+ } else if (offs > 0) {
+ nd->nd_dpos += offs;
+ nd->nd_dextpgsiz -= offs;
+ offs = 0;
+ }
+ } while (offs > 0);
}
} else if (build) {
- nd->nd_bpos = mtod(m, char *);
- rlen = m->m_len;
+ nd->nd_bpos = mtod(m, char *) + offs;
+ rlen = m->m_len - offs;
} else {
nd->nd_dpos = mtod(m, char *);
rlen = m->m_len;
@@ -5026,6 +5052,7 @@ nfsm_splitatpgno(struct mbuf *mp, int pgno, int how)
if (m == NULL)
return (m);
pgs0 = m->m_ext.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++)
@@ -5066,7 +5093,7 @@ 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, false);
+ *leftp = nfsm_set(nd, 0, false);
return (true);
}
@@ -5105,70 +5132,28 @@ nfsm_add_ext_pgs(struct mbuf *m, int maxextsiz, int *b
}
/*
- * Trim the ext_pgs mbuf to the current dissect position.
+ * Calculate the data offset of m for dextpg and dextpgsiz.
*/
-void
-nfsm_trimatpos_extpgs(struct nfsrv_descript *nd)
+int
+nfsm_extpgs_calc_offs(struct mbuf *m, int dextpg, int dextpgsiz)
{
struct mbuf_ext_pgs *pgs;
- vm_page_t pg;
- int i, j;
+ int cnt, offs;
- pgs = nd->nd_md->m_ext.ext_pgs;
- for (i = 0; i < nd->nd_dextpg; i++) {
- pg = PHYS_TO_VM_PAGE(pgs->pa[0]);
- vm_page_unwire_noq(pg);
- vm_page_free(pg);
- nd->nd_md->m_len -= mbuf_ext_pg_len(pgs, i,
- pgs->first_pg_off);
- pgs->first_pg_off = 0;
- for (j = 0; j < pgs->npgs - 1; j++)
- pgs->pa[j] = pgs->pa[j + 1];
- pgs->npgs--;
- }
- nd->nd_dextpg = 0;
- if (nd->nd_dextpgsiz > 0) {
- j = mbuf_ext_pg_len(pgs, 0, pgs->first_pg_off);
- j -= nd->nd_dextpgsiz;
- pgs->first_pg_off += j;
- nd->nd_md->m_len -= j;
- if (nd->nd_dextpg == pgs->npgs - 1)
- pgs->last_pg_len -= j;
- }
-}
-
-/*
- * Trim the ext_pgs mbuf back to "tlen" bytes in length.
- */
-void
-nfsm_trimback_extpgs(struct mbuf *m, int len)
-{
- struct mbuf_ext_pgs *pgs;
- vm_page_t pg;
- int i, j, pgno, tlen;
-
+ offs = 0;
pgs = m->m_ext.ext_pgs;
- pgno = 0;
- tlen = len;
- while (len > 0 && pgno < pgs->npgs) {
- if (pgno == 0)
- i = mbuf_ext_pg_len(pgs, pgno,
+ for (cnt = 0; cnt < dextpg; cnt++) {
+ if (cnt == 0)
+ offs += mbuf_ext_pg_len(pgs, 0,
pgs->first_pg_off);
else
- i = mbuf_ext_pg_len(pgs, pgno, 0);
- if (len <= i) {
- /* Free pages past pgno. */
- for (j = pgno + 1; j < pgs->npgs; j++) {
- pg = PHYS_TO_VM_PAGE(pgs->pa[j]);
- vm_page_unwire_noq(pg);
- vm_page_free(pg);
- }
- pgs->npgs = pgno + 1;
- pgs->last_pg_len = len;
- }
- len -= i;
- pgno++;
+ offs += mbuf_ext_pg_len(pgs, cnt, 0);
}
- m->m_len = tlen;
+ 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 Mar 8 18:54:59 2020 (r358769)
+++ projects/nfs-over-tls/sys/fs/nfs/nfs_var.h Sun Mar 8 19:02:30 2020 (r358770)
@@ -361,14 +361,13 @@ int nfsv4_sequencelookup(struct nfsmount *, struct nfs
void nfsv4_freeslot(struct nfsclsession *, int);
struct ucred *nfsrv_getgrpscred(struct ucred *);
struct nfsdevice *nfsv4_findmirror(struct nfsmount *);
-int nfsm_set(struct nfsrv_descript *, bool);
+int nfsm_set(struct nfsrv_descript *, u_int, bool);
bool nfsm_shiftnext(struct nfsrv_descript *, int *);
-void nfsm_trimatpos_extpgs(struct nfsrv_descript *);
-void nfsm_trimback_extpgs(struct mbuf *, int);
+int nfsm_extpgs_calc_offs(struct mbuf *, int, int);
/* nfs_clcomsubs.c */
void nfsm_uiombuf(struct nfsrv_descript *, struct uio *, int);
-struct mbuf *nfsm_uiombuflist(int, int, struct uio *, int, struct mbuf **, char **);
+struct mbuf *nfsm_uiombuflist(bool, int, struct uio *, int, struct mbuf **, char **);
nfsuint64 *nfscl_getcookie(struct nfsnode *, off_t off, int);
u_int8_t *nfscl_getmyip(struct nfsmount *, struct in6_addr *, int *);
int nfsm_getfh(struct nfsrv_descript *, struct nfsfh **);
@@ -687,8 +686,8 @@ int nfsvno_readlink(vnode_t, struct ucred *, int, NFSP
mbuf_t *, int *);
int nfsvno_read(vnode_t, off_t, int, struct ucred *, int, NFSPROC_T *,
mbuf_t *, mbuf_t *);
-int nfsvno_write(vnode_t, off_t, int, int *, mbuf_t, char *, int, int,
- struct ucred *, NFSPROC_T *);
+int nfsvno_write(vnode_t, off_t, int, int *, struct nfsrv_descript *,
+ NFSPROC_T *);
int nfsvno_createsub(struct nfsrv_descript *, struct nameidata *,
vnode_t *, struct nfsvattr *, int *, int32_t *, NFSDEV_T,
struct nfsexstuff *);
More information about the svn-src-projects
mailing list