untrusted comment: verify with openbsd-79-base.pub
RWTSdNN9A3yvWNpfdP59RWrqvfS0vaISPQf3xm0pZY81QEiweRI5B/RJlnWLXHL3Z/qb6XKN27cJLc2OpyezGj0GOkJ0O22aXQk=

OpenBSD 7.9 errata 006, July 16, 2026:

Fix double-free, memory leaks, and vnode references in NFS server.

Apply by doing:
    signify -Vep /etc/signify/openbsd-79-base.pub -x 006_nfs.patch.sig \
        -m - | (cd /usr/src && patch -p0)

And then rebuild and install a new kernel:
    KK=`sysctl -n kern.osversion | cut -d# -f1`
    cd /usr/src/sys/arch/`machine`/compile/$KK
    make obj
    make config
    make
    make install

Index: sys/nfs/nfs_serv.c
===================================================================
RCS file: /cvs/src/sys/nfs/nfs_serv.c,v
diff -u -p -r1.133 nfs_serv.c
--- sys/nfs/nfs_serv.c	4 May 2026 17:05:59 -0000	1.133
+++ sys/nfs/nfs_serv.c	9 Jul 2026 13:50:44 -0000
@@ -86,48 +86,54 @@ extern struct nfsstats nfsstats;
 int nfsrv_access(struct vnode *, int, struct ucred *, int, struct proc *, int);
 
 static inline int
-nfsm_reply(struct nfsm_info *infop, struct nfsrv_descript *nfsd,
-    struct nfssvc_sock *slp, struct mbuf **mrq, int error, int statuslen)
+nfsm_reply(struct nfsrv_descript *nfsd,
+    struct nfssvc_sock *slp, struct mbuf **mrq, struct mbuf **mb,
+    int error, int statuslen)
 {
+	struct mbuf *mreq = NULL;
+	int v3 = nfsd->nd_flag & ND_NFSV3;
+
 	nfsd->nd_repstat = error;
-	if (error && !infop->nmi_v3)
+	if (error && !v3)
 		statuslen = 0;
 	(void)nfs_rephead(statuslen, nfsd, slp, error,
-		&infop->nmi_mreq, &infop->nmi_mb);
-	m_freem(infop->nmi_mrep);
-	infop->nmi_mrep = NULL;
-	*mrq = infop->nmi_mreq;
-	if (error && (!infop->nmi_v3 || error == EBADRPC))
+		&mreq, mb);
+	m_freem(nfsd->nd_mrep);
+	nfsd->nd_mrep = NULL;
+	*mrq = mreq;
+	if (error && (!v3 || error == EBADRPC))
 		return error;
 	return 0;
 }
 
 static inline int
-nfsm_srvmtofh1(struct nfsm_info *infop, struct nfsrv_descript *nfsd,
-    struct nfssvc_sock *slp, struct mbuf **mrq)
-{
-	if (infop->nmi_v3) {
-		uint32_t *tl = (uint32_t *)nfsm_dissect(infop, NFSX_UNSIGNED);
+nfsm_srvmtofh1(struct nfsrv_descript *nfsd,
+    struct nfssvc_sock *slp, struct mbuf **mrq, struct mbuf **mb,
+    int *errorp)
+{
+	if (nfsd->nd_flag & ND_NFSV3) {
+		uint32_t *tl = (uint32_t *)nfsd_dissect(nfsd, NFSX_UNSIGNED,
+		    errorp);
 		if (tl == NULL)
-			return 0; /* *infop->nmi_errorp set */
+			return 0; /* *errorp set */
 		if (fxdr_unsigned(int, *tl) != NFSX_V3FH) {
-			*infop->nmi_errorp = EBADRPC;
-			return nfsm_reply(infop, nfsd, slp, mrq,
-			    *infop->nmi_errorp, 0);
+			*errorp = EBADRPC;
+			return nfsm_reply(nfsd, slp, mrq, mb,
+			    *errorp, 0);
 		}
 	}
 	return 0;
 }
 
 static inline int
-nfsm_srvmtofh2(struct nfsm_info *infop, fhandle_t *fhp)
+nfsm_srvmtofh2(struct nfsrv_descript *nfsd, fhandle_t *fhp, int *errorp)
 {
-	uint32_t *tl = (uint32_t *)nfsm_dissect(infop, NFSX_V3FH);
+	uint32_t *tl = (uint32_t *)nfsd_dissect(nfsd, NFSX_V3FH, errorp);
 	if (tl == NULL)
 		return 1;
 	bcopy(tl, fhp, NFSX_V3FH);
-	if (infop->nmi_v3 == 0) {
-		if (nfsm_adv(infop, NFSX_V2FH - NFSX_V3FH) != 0)
+	if ((nfsd->nd_flag & ND_NFSV3) == 0) {
+		if (nfsd_adv(nfsd, NFSX_V2FH - NFSX_V3FH, errorp) != 0)
 			return 1;
 	}
 	return 0;
@@ -141,7 +147,7 @@ nfsrv3_access(struct nfsrv_descript *nfs
     struct proc *procp, struct mbuf **mrq)
 {
 	struct mbuf *nam = nfsd->nd_nam;
-	struct nfsm_info	info;
+	struct mbuf *mb;
 	struct ucred *cred = &nfsd->nd_cr;
 	struct vnode *vp;
 	nfsfh_t nfh;
@@ -151,29 +157,22 @@ nfsrv3_access(struct nfsrv_descript *nfs
 	struct vattr va;
 	u_long testmode, nfsmode;
 
-	info.nmi_mreq = NULL;
-	info.nmi_mrep = nfsd->nd_mrep;
-	info.nmi_md = nfsd->nd_md;
-	info.nmi_dpos = nfsd->nd_dpos;
-	info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
-	info.nmi_errorp = &error;
-
-	if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+	if (nfsm_srvmtofh1(nfsd, slp, mrq, &mb, &error) != 0)
 		return 0;
 	else if (error != 0)
 		goto nfsmout;
 	fhp = &nfh.fh_generic;
-	if (nfsm_srvmtofh2(&info, fhp) != 0)
+	if (nfsm_srvmtofh2(nfsd, fhp, &error) != 0)
 		goto nfsmout;
-	tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+	tl = (uint32_t *)nfsd_dissect(nfsd, NFSX_UNSIGNED, &error);
 	if (tl == NULL)
 		goto nfsmout;
 	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
 	if (error) {
-		if (nfsm_reply(&info, nfsd, slp, mrq, error,
+		if (nfsm_reply(nfsd, slp, mrq, &mb, error,
 		    NFSX_UNSIGNED) != 0)
 			return 0;
-		nfsm_srvpostop_attr(nfsd, 1, NULL, &info);
+		nfsm_srvpostop_attr(nfsd, 1, NULL, &mb);
 		error = 0;
 		goto nfsmout;
 	}
@@ -198,11 +197,11 @@ nfsrv3_access(struct nfsrv_descript *nfs
 		nfsmode &= ~testmode;
 	getret = VOP_GETATTR(vp, &va, cred, procp);
 	vput(vp);
-	if (nfsm_reply(&info, nfsd, slp, mrq, error,
+	if (nfsm_reply(nfsd, slp, mrq, &mb, error,
 	    NFSX_POSTOPATTR(1) + NFSX_UNSIGNED) != 0)
 		return 0;
-	nfsm_srvpostop_attr(nfsd, getret, &va, &info);
-	tl = nfsm_build(&info.nmi_mb, NFSX_UNSIGNED);
+	nfsm_srvpostop_attr(nfsd, getret, &va, &mb);
+	tl = nfsm_build(&mb, NFSX_UNSIGNED);
 	*tl = txdr_unsigned(nfsmode);
 nfsmout:
 	return(error);
@@ -216,7 +215,7 @@ nfsrv_getattr(struct nfsrv_descript *nfs
     struct proc *procp, struct mbuf **mrq)
 {
 	struct mbuf *nam = nfsd->nd_nam;
-	struct nfsm_info	info;
+	struct mbuf *mb;
 	struct ucred *cred = &nfsd->nd_cr;
 	struct nfs_fattr *fp;
 	struct vattr va;
@@ -225,37 +224,31 @@ nfsrv_getattr(struct nfsrv_descript *nfs
 	fhandle_t *fhp;
 	int error = 0, rdonly;
 
-	info.nmi_mreq = NULL;
-	info.nmi_mrep = nfsd->nd_mrep;
-	info.nmi_md = nfsd->nd_md;
-	info.nmi_dpos = nfsd->nd_dpos;
-	info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
-	info.nmi_errorp = &error;
-
-	if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+	if (nfsm_srvmtofh1(nfsd, slp, mrq, &mb, &error) != 0)
 		return 0;
 	else if (error != 0)
 		goto nfsmout;
 	fhp = &nfh.fh_generic;
-	if (nfsm_srvmtofh2(&info, fhp) != 0)
+	if (nfsm_srvmtofh2(nfsd, fhp, &error) != 0)
 		goto nfsmout;
 	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
 	if (error) {
-		if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0)
+		if (nfsm_reply(nfsd, slp, mrq, &mb,
+		    error, 0) != 0)
 			return 0;
 		error = 0;
 		goto nfsmout;
 	}
 	error = VOP_GETATTR(vp, &va, cred, procp);
 	vput(vp);
-	if (nfsm_reply(&info, nfsd, slp, mrq, error,
+	if (nfsm_reply(nfsd, slp, mrq, &mb, error,
 	    NFSX_FATTR(nfsd->nd_flag & ND_NFSV3)) != 0)
 		return 0;
 	if (error) {
 		error = 0;
 		goto nfsmout;
 	}
-	fp = nfsm_build(&info.nmi_mb, NFSX_FATTR(nfsd->nd_flag & ND_NFSV3));
+	fp = nfsm_build(&mb, NFSX_FATTR(nfsd->nd_flag & ND_NFSV3));
 	nfsm_srvfattr(nfsd, &va, fp);
 nfsmout:
 	return(error);
@@ -269,7 +262,7 @@ nfsrv_setattr(struct nfsrv_descript *nfs
     struct proc *procp, struct mbuf **mrq)
 {
 	struct mbuf *nam = nfsd->nd_nam;
-	struct nfsm_info	info;
+	struct mbuf *mb;
 	struct ucred *cred = &nfsd->nd_cr;
 	struct vattr va, preat;
 	struct nfsv2_sattr *sp;
@@ -281,39 +274,37 @@ nfsrv_setattr(struct nfsrv_descript *nfs
 	int error = 0, rdonly, preat_ret = 1, postat_ret = 1;
 	int gcheck = 0;
 	struct timespec guard;
+	int v3;
 
-	info.nmi_mreq = NULL;
-	info.nmi_mrep = nfsd->nd_mrep;
-	info.nmi_md = nfsd->nd_md;
-	info.nmi_dpos = nfsd->nd_dpos;
-	info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
-	info.nmi_errorp = &error;
+	v3 = (nfsd->nd_flag & ND_NFSV3);
 
-	if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+	if (nfsm_srvmtofh1(nfsd, slp, mrq, &mb, &error) != 0)
 		return 0;
 	else if (error != 0)
 		goto nfsmout;
 	fhp = &nfh.fh_generic;
-	if (nfsm_srvmtofh2(&info, fhp) != 0)
+	if (nfsm_srvmtofh2(nfsd, fhp, &error) != 0)
 		goto nfsmout;
 	vattr_null(&va);
-	if (info.nmi_v3) {
+	if (v3) {
 		va.va_vaflags |= VA_UTIMES_NULL;
-		error = nfsm_srvsattr(&info.nmi_md, &va, info.nmi_mrep, &info.nmi_dpos);
+		error = nfsm_srvsattr(nfsd, &va);
 		if (error)
 			goto nfsmout;
-		tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+		tl = (uint32_t *)nfsd_dissect(nfsd, NFSX_UNSIGNED, &error);
 		if (tl == NULL)
 			goto nfsmout;
 		gcheck = fxdr_unsigned(int, *tl);
 		if (gcheck) {
-			tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED);
+			tl = (uint32_t *)nfsd_dissect(nfsd, 2 * NFSX_UNSIGNED,
+			    &error);
 			if (tl == NULL)
 				goto nfsmout;
 			fxdr_nfsv3time(tl, &guard);
 		}
 	} else {
-		sp = (struct nfsv2_sattr *)nfsm_dissect(&info, NFSX_V2SATTR);
+		sp = (struct nfsv2_sattr *)nfsd_dissect(nfsd, NFSX_V2SATTR,
+		    &error);
 		if (sp == NULL)
 			goto nfsmout;
 		/*
@@ -350,14 +341,14 @@ nfsrv_setattr(struct nfsrv_descript *nfs
 	 */
 	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
 	if (error) {
-		if (nfsm_reply(&info, nfsd, slp, mrq, error,
+		if (nfsm_reply(nfsd, slp, mrq, &mb, error,
 		    2 * NFSX_UNSIGNED) != 0)
 			return 0;
-		nfsm_srvwcc(nfsd, preat_ret, &preat, postat_ret, &va, &info);
+		nfsm_srvwcc(nfsd, preat_ret, &preat, postat_ret, &va, &mb);
 		error = 0;
 		goto nfsmout;
 	}
-	if (info.nmi_v3) {
+	if (v3) {
 		error = preat_ret = VOP_GETATTR(vp, &preat, cred, procp);
 		if (!error && gcheck &&
 			(preat.va_ctime.tv_sec != guard.tv_sec ||
@@ -365,11 +356,11 @@ nfsrv_setattr(struct nfsrv_descript *nfs
 			error = NFSERR_NOT_SYNC;
 		if (error) {
 			vput(vp);
-			if (nfsm_reply(&info, nfsd, slp, mrq, error,
-			    NFSX_WCCDATA(info.nmi_v3)) != 0)
+			if (nfsm_reply(nfsd, slp, mrq, &mb, error,
+			    NFSX_WCCDATA(v3)) != 0)
 				return 0;
 			nfsm_srvwcc(nfsd, preat_ret, &preat, postat_ret, &va,
-			    &info);
+			    &mb);
 			error = 0;
 			goto nfsmout;
 		}
@@ -398,16 +389,15 @@ nfsrv_setattr(struct nfsrv_descript *nfs
 		error = postat_ret;
 out:
 	vput(vp);
-	if (nfsm_reply(&info, nfsd, slp, mrq, error,
-	    NFSX_WCCORFATTR(info.nmi_v3)) != 0)
+	if (nfsm_reply(nfsd, slp, mrq, &mb, error, NFSX_WCCORFATTR(v3)) != 0)
 		return 0;
-	if (info.nmi_v3) {
+	if (v3) {
 		nfsm_srvwcc(nfsd, preat_ret, &preat, postat_ret, &va,
-		    &info);
+		    &mb);
 		error = 0;
 		goto nfsmout;
 	} else {
-		fp = nfsm_build(&info.nmi_mb, NFSX_V2FATTR);
+		fp = nfsm_build(&mb, NFSX_V2FATTR);
 		nfsm_srvfattr(nfsd, &va, fp);
 	}
 nfsmout:
@@ -415,21 +405,21 @@ nfsmout:
 }
 
 static inline int
-nfsm_srvnamesiz(struct nfsm_info *infop, int *lenp)
+nfsm_srvnamesiz(struct nfsrv_descript *nfsd, int *lenp, int *errorp)
 {
 	int len;
-	uint32_t *tl = (uint32_t *)nfsm_dissect(infop, NFSX_UNSIGNED);
+	uint32_t *tl = (uint32_t *)nfsd_dissect(nfsd, NFSX_UNSIGNED, errorp);
 	if (tl == NULL)
 		return 1;
 	len = fxdr_unsigned(int32_t, *tl);
 	if (len > NFS_MAXNAMLEN) {
-		*infop->nmi_errorp = NFSERR_NAMETOL;
+		*errorp = NFSERR_NAMETOL;
 		*lenp = 0;
 	} else if (len <= 0) {
-		*infop->nmi_errorp = EBADRPC;
+		*errorp = EBADRPC;
 		*lenp = 0;
 	} else {
-		*infop->nmi_errorp = 0;
+		*errorp = 0;
 		*lenp = len;
 	}
 	return 0;
@@ -443,32 +433,25 @@ nfsrv_lookup(struct nfsrv_descript *nfsd
     struct proc *procp, struct mbuf **mrq)
 {
 	struct mbuf *nam = nfsd->nd_nam;
+	struct mbuf *mb;
 	struct ucred *cred = &nfsd->nd_cr;
 	struct nfs_fattr *fp;
 	struct nameidata nd;
 	struct vnode *vp, *dirp;
-	struct nfsm_info	info;
 	nfsfh_t nfh;
 	fhandle_t *fhp;
 	int error = 0, len, dirattr_ret = 1;
 	int v3 = (nfsd->nd_flag & ND_NFSV3);
 	struct vattr va, dirattr;
 
-	info.nmi_mrep = nfsd->nd_mrep;
-	info.nmi_mreq = NULL;
-	info.nmi_md = nfsd->nd_md;
-	info.nmi_dpos = nfsd->nd_dpos;
-	info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
-	info.nmi_errorp = &error;
-
-	if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+	if (nfsm_srvmtofh1(nfsd, slp, mrq, &mb, &error) != 0)
 		return 0;
 	else if (error != 0)
 		goto nfsmout;
 	fhp = &nfh.fh_generic;
-	if (nfsm_srvmtofh2(&info, fhp) != 0)
+	if (nfsm_srvmtofh2(nfsd, fhp, &error) != 0)
 		goto nfsmout;
-	if (nfsm_srvnamesiz(&info, &len) != 0)
+	if (nfsm_srvnamesiz(nfsd, &len, &error) != 0)
 		goto nfsmout;
 	if (error) {
 		/*
@@ -476,24 +459,24 @@ nfsrv_lookup(struct nfsrv_descript *nfsd
 		 * from EBADRPC. But it does not make sense to continue
 		 * anyway if the error set in nfsm_srvnamesiz is NFSERR_NAMETOL.
 		 */
-		(void)nfsm_reply(&info, nfsd, slp, mrq, error, 0);
+		(void)nfsm_reply(nfsd, slp, mrq, &mb, error, 0);
 		return 0;
 	}
 
 	NDINIT(&nd, LOOKUP, LOCKLEAF | SAVESTART, UIO_SYSSPACE, NULL, procp);
 	nd.ni_cnd.cn_cred = cred;
-	error = nfs_namei(&nd, fhp, len, slp, nam, &info.nmi_md, &info.nmi_dpos, &dirp, procp);
+	error = nfs_namei(&nd, fhp, len, slp, nam, &nfsd->nd_md, &nfsd->nd_dpos, &dirp, procp);
 	if (dirp) {
-		if (info.nmi_v3)
+		if (v3)
 			dirattr_ret = VOP_GETATTR(dirp, &dirattr, cred,
 				procp);
 		vrele(dirp);
 	}
 	if (error) {
-		if (nfsm_reply(&info, nfsd, slp, mrq, error,
-		    NFSX_POSTOPATTR(info.nmi_v3)) != 0)
+		if (nfsm_reply(nfsd, slp, mrq, &mb, error,
+		    NFSX_POSTOPATTR(v3)) != 0)
 			return 0;
-		nfsm_srvpostop_attr(nfsd, dirattr_ret, &dirattr, &info);
+		nfsm_srvpostop_attr(nfsd, dirattr_ret, &dirattr, &mb);
 		return (0);
 	}
 	vrele(nd.ni_startdir);
@@ -505,21 +488,20 @@ nfsrv_lookup(struct nfsrv_descript *nfsd
 	if (!error)
 		error = VOP_GETATTR(vp, &va, cred, procp);
 	vput(vp);
-	if (nfsm_reply(&info, nfsd, slp, mrq, error,
-	    NFSX_SRVFH(info.nmi_v3) + NFSX_POSTOPORFATTR(info.nmi_v3) +
-	    NFSX_POSTOPATTR(info.nmi_v3)) != 0)
+	if (nfsm_reply(nfsd, slp, mrq, &mb, error,
+	    NFSX_SRVFH(v3) + NFSX_POSTOPORFATTR(v3) + NFSX_POSTOPATTR(v3)) != 0)
 		return 0;
 	if (error) {
-		nfsm_srvpostop_attr(nfsd, dirattr_ret, &dirattr, &info);
+		nfsm_srvpostop_attr(nfsd, dirattr_ret, &dirattr, &mb);
 		error = 0;
 		goto nfsmout;
 	}
-	nfsm_srvfhtom(&info.nmi_mb, fhp, info.nmi_v3);
+	nfsm_srvfhtom(&mb, fhp, v3);
 	if (v3) {
-		nfsm_srvpostop_attr(nfsd, 0, &va, &info);
-		nfsm_srvpostop_attr(nfsd, dirattr_ret, &dirattr, &info);
+		nfsm_srvpostop_attr(nfsd, 0, &va, &mb);
+		nfsm_srvpostop_attr(nfsd, dirattr_ret, &dirattr, &mb);
 	} else {
-		fp = nfsm_build(&info.nmi_mb, NFSX_V2FATTR);
+		fp = nfsm_build(&mb, NFSX_V2FATTR);
 		nfsm_srvfattr(nfsd, &va, fp);
 	}
 nfsmout:
@@ -534,10 +516,10 @@ nfsrv_readlink(struct nfsrv_descript *nf
     struct proc *procp, struct mbuf **mrq)
 {
 	struct mbuf *nam = nfsd->nd_nam;
+	struct mbuf *mb;
 	struct ucred *cred = &nfsd->nd_cr;
 	struct iovec iov;
 	struct mbuf *mp = NULL;
-	struct nfsm_info	info;
 	u_int32_t *tl;
 	int error = 0, rdonly, tlen, len = 0, getret;
 	struct vnode *vp;
@@ -545,34 +527,30 @@ nfsrv_readlink(struct nfsrv_descript *nf
 	nfsfh_t nfh;
 	fhandle_t *fhp;
 	struct uio uio;
+	int v3;
 
-	info.nmi_mreq = NULL;
-	info.nmi_mrep = nfsd->nd_mrep;
-	info.nmi_md = nfsd->nd_md;
-	info.nmi_dpos = nfsd->nd_dpos;
-	info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
-	info.nmi_errorp = &error;
+	v3 = (nfsd->nd_flag & ND_NFSV3);
 
 	memset(&uio, 0, sizeof(uio));
 
-	if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+	if (nfsm_srvmtofh1(nfsd, slp, mrq, &mb, &error) != 0)
 		return 0;
 	else if (error != 0)
 		goto nfsmout;
 	fhp = &nfh.fh_generic;
-	if (nfsm_srvmtofh2(&info, fhp) != 0)
+	if (nfsm_srvmtofh2(nfsd, fhp, &error) != 0)
 		goto nfsmout;
 	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
 	if (error) {
-		if (nfsm_reply(&info, nfsd, slp, mrq, error,
+		if (nfsm_reply(nfsd, slp, mrq, &mb, error,
 		    2 * NFSX_UNSIGNED) != 0)
 			return 0;
-		nfsm_srvpostop_attr(nfsd, 1, NULL, &info);
+		nfsm_srvpostop_attr(nfsd, 1, NULL, &mb);
 		error = 0;
 		goto nfsmout;
 	}
 	if (vp->v_type != VLNK) {
-		if (info.nmi_v3)
+		if (v3)
 			error = EINVAL;
 		else
 			error = ENXIO;
@@ -600,11 +578,11 @@ out:
 	vput(vp);
 	if (error)
 		m_freem(mp);
-	if (nfsm_reply(&info, nfsd, slp, mrq, error,
-	    NFSX_POSTOPATTR(info.nmi_v3) + NFSX_UNSIGNED) != 0)
+	if (nfsm_reply(nfsd, slp, mrq, &mb, error,
+	    NFSX_POSTOPATTR(v3) + NFSX_UNSIGNED) != 0)
 		return 0;
-	if (info.nmi_v3) {
-		nfsm_srvpostop_attr(nfsd, getret, &attr, &info);
+	if (v3) {
+		nfsm_srvpostop_attr(nfsd, getret, &attr, &mb);
 		if (error) {
 			error = 0;
 			goto nfsmout;
@@ -615,9 +593,9 @@ out:
 		tlen = nfsm_rndup(len);
 		nfsm_adj(mp, NFS_MAXPATHLEN-tlen, tlen-len);
 	}
-	tl = nfsm_build(&info.nmi_mb, NFSX_UNSIGNED);
+	tl = nfsm_build(&mb, NFSX_UNSIGNED);
 	*tl = txdr_unsigned(len);
-	info.nmi_mb->m_next = mp;
+	mb->m_next = mp;
 
 nfsmout:
 	return (error);
@@ -631,10 +609,10 @@ nfsrv_read(struct nfsrv_descript *nfsd, 
     struct proc *procp, struct mbuf **mrq)
 {
 	struct mbuf *nam = nfsd->nd_nam;
+	struct mbuf *mb;
 	struct ucred *cred = &nfsd->nd_cr;
 	struct mbuf *m;
 	struct nfs_fattr *fp;
-	struct nfsm_info	info;
 	u_int32_t *tl;
 	int i, reqlen;
 	int error = 0, rdonly, cnt, len, left, siz, tlen, getret = 1;
@@ -645,40 +623,37 @@ nfsrv_read(struct nfsrv_descript *nfsd, 
 	struct uio io, *uiop = &io;
 	struct vattr va;
 	off_t off;
+	int v3;
 
-	info.nmi_mreq = NULL;
-	info.nmi_mrep = nfsd->nd_mrep;
-	info.nmi_md = nfsd->nd_md;
-	info.nmi_dpos = nfsd->nd_dpos;
-	info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
-	info.nmi_errorp = &error;
+	v3 = (nfsd->nd_flag & ND_NFSV3);
 
-	if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+	if (nfsm_srvmtofh1(nfsd, slp, mrq, &mb, &error) != 0)
 		return 0;
 	else if (error != 0)
 		goto nfsmout;
 	fhp = &nfh.fh_generic;
-	if (nfsm_srvmtofh2(&info, fhp) != 0)
+	if (nfsm_srvmtofh2(nfsd, fhp, &error) != 0)
 		goto nfsmout;
-	if (info.nmi_v3) {
-		tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED);
+	if (v3) {
+		tl = (uint32_t *)nfsd_dissect(nfsd, 2 * NFSX_UNSIGNED, &error);
 		if (tl == NULL)
 			goto nfsmout;
 		off = fxdr_hyper(tl);
 	} else {
-		tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+		tl = (uint32_t *)nfsd_dissect(nfsd, NFSX_UNSIGNED, &error);
 		if (tl == NULL)
 			goto nfsmout;
 		off = (off_t)fxdr_unsigned(u_int32_t, *tl);
 	}
 
-	tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+	tl = (uint32_t *)nfsd_dissect(nfsd, NFSX_UNSIGNED, &error);
 	if (tl == NULL)
 		goto nfsmout;
 	reqlen = fxdr_unsigned(int32_t, *tl);
 	if (reqlen > (NFS_SRVMAXDATA(nfsd)) || reqlen <= 0) {
 		error = EBADRPC;
-		if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0)
+		if (nfsm_reply(nfsd, slp, mrq, &mb,
+		    error, 0) != 0)
 			return 0;
 	}
 
@@ -687,7 +662,7 @@ nfsrv_read(struct nfsrv_descript *nfsd, 
 		goto bad;
 
 	if (vp->v_type != VREG) {
-		if (info.nmi_v3)
+		if (v3)
 			error = EINVAL;
 		else
 			error = (vp->v_type == VDIR) ? EISDIR : EACCES;
@@ -708,17 +683,16 @@ nfsrv_read(struct nfsrv_descript *nfsd, 
 		cnt = va.va_size - off;
 	else
 		cnt = reqlen;
-	if (nfsm_reply(&info, nfsd, slp, mrq, error,
-	    NFSX_POSTOPORFATTR(info.nmi_v3) +
-	    3 * NFSX_UNSIGNED+nfsm_rndup(cnt)) != 0)
+	if (nfsm_reply(nfsd, slp, mrq, &mb, error,
+	    NFSX_POSTOPORFATTR(v3) + 3 * NFSX_UNSIGNED+nfsm_rndup(cnt)) != 0)
 		return 0;
-	if (info.nmi_v3) {
-		tl = nfsm_build(&info.nmi_mb, NFSX_V3FATTR + 4 * NFSX_UNSIGNED);
+	if (v3) {
+		tl = nfsm_build(&mb, NFSX_V3FATTR + 4 * NFSX_UNSIGNED);
 		*tl++ = nfs_true;
 		fp = (struct nfs_fattr *)tl;
 		tl += (NFSX_V3FATTR / sizeof (u_int32_t));
 	} else {
-		tl = nfsm_build(&info.nmi_mb, NFSX_V2FATTR + NFSX_UNSIGNED);
+		tl = nfsm_build(&mb, NFSX_V2FATTR + NFSX_UNSIGNED);
 		fp = (struct nfs_fattr *)tl;
 		tl += (NFSX_V2FATTR / sizeof (u_int32_t));
 	}
@@ -730,7 +704,7 @@ nfsrv_read(struct nfsrv_descript *nfsd, 
 		 * Generate the mbuf list with the uio_iov ref. to it.
 		 */
 		i = 0;
-		m = m2 = info.nmi_mb;
+		m = m2 = mb;
 		while (left > 0) {
 			siz = min(m_trailingspace(m), left);
 			if (siz > 0) {
@@ -749,7 +723,7 @@ nfsrv_read(struct nfsrv_descript *nfsd, 
 		iv = mallocarray(i, sizeof(*iv), M_TEMP, M_WAITOK);
 		ivlen = i * sizeof(*iv);
 		uiop->uio_iov = iv2 = iv;
-		m = info.nmi_mb;
+		m = mb;
 		left = len;
 		i = 0;
 		while (left > 0) {
@@ -777,7 +751,6 @@ nfsrv_read(struct nfsrv_descript *nfsd, 
 		if (error || (getret = VOP_GETATTR(vp, &va, cred, procp)) != 0){
 			if (!error)
 				error = getret;
-			m_freem(info.nmi_mreq);
 			goto vbad;
 		}
 	} else
@@ -788,8 +761,8 @@ nfsrv_read(struct nfsrv_descript *nfsd, 
 	cnt = cnt < tlen ? cnt : tlen;
 	tlen = nfsm_rndup (cnt);
 	if (len != tlen || tlen != cnt)
-		nfsm_adj(info.nmi_mb, len - tlen, tlen - cnt);
-	if (info.nmi_v3) {
+		nfsm_adj(mb, len - tlen, tlen - cnt);
+	if (v3) {
 		*tl++ = txdr_unsigned(cnt);
 		if (len < reqlen)
 			*tl++ = nfs_true;
@@ -803,9 +776,9 @@ nfsmout:
 vbad:
 	vput(vp);
 bad:
-	if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0)
+	if (nfsm_reply(nfsd, slp, mrq, &mb, error, 0) != 0)
 		return 0;
-	nfsm_srvpostop_attr(nfsd, getret, &va, &info);
+	nfsm_srvpostop_attr(nfsd, getret, &va, &mb);
 	return (0);
 }
 
@@ -817,8 +790,8 @@ nfsrv_write(struct nfsrv_descript *nfsd,
     struct proc *procp, struct mbuf **mrq)
 {
 	struct mbuf *nam = nfsd->nd_nam;
+	struct mbuf *mb;
 	struct ucred *cred = &nfsd->nd_cr;
-	struct nfsm_info	info;
 	int i, cnt;
 	struct mbuf *mp;
 	struct nfs_fattr *fp;
@@ -833,34 +806,30 @@ nfsrv_write(struct nfsrv_descript *nfsd,
 	fhandle_t *fhp;
 	struct uio io, *uiop = &io;
 	off_t off;
+	int v3;
 
-	info.nmi_mreq = NULL;
-	info.nmi_mrep = nfsd->nd_mrep;
-	info.nmi_md = nfsd->nd_md;
-	info.nmi_dpos = nfsd->nd_dpos;
-	info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
-	info.nmi_errorp = &error;
+	v3 = (nfsd->nd_flag & ND_NFSV3);
 
-	if (info.nmi_mrep == NULL) {
+	if (nfsd->nd_mrep == NULL) {
 		*mrq = NULL;
 		return (0);
 	}
-	if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+	if (nfsm_srvmtofh1(nfsd, slp, mrq, &mb, &error) != 0)
 		return 0;
 	else if (error != 0)
 		goto nfsmout;
 	fhp = &nfh.fh_generic;
-	if (nfsm_srvmtofh2(&info, fhp) != 0)
+	if (nfsm_srvmtofh2(nfsd, fhp, &error) != 0)
 		goto nfsmout;
-	if (info.nmi_v3) {
-		tl = (uint32_t *)nfsm_dissect(&info, 5 * NFSX_UNSIGNED);
+	if (v3) {
+		tl = (uint32_t *)nfsd_dissect(nfsd, 5 * NFSX_UNSIGNED, &error);
 		if (tl == NULL)
 			goto nfsmout;
 		off = fxdr_hyper(tl);
 		tl += 3;
 		stable = fxdr_unsigned(int, *tl++);
 	} else {
-		tl = (uint32_t *)nfsm_dissect(&info, 4 * NFSX_UNSIGNED);
+		tl = (uint32_t *)nfsd_dissect(nfsd, 4 * NFSX_UNSIGNED, &error);
 		if (tl == NULL)
 			goto nfsmout;
 		off = (off_t)fxdr_unsigned(u_int32_t, *++tl);
@@ -876,11 +845,11 @@ nfsrv_write(struct nfsrv_descript *nfsd,
 	 */
 	if (len > 0) {
 	    zeroing = 1;
-	    mp = info.nmi_mrep;
+	    mp = nfsd->nd_mrep;
 	    while (mp) {
-		if (mp == info.nmi_md) {
+		if (mp == nfsd->nd_md) {
 			zeroing = 0;
-			adjust = info.nmi_dpos - mtod(mp, caddr_t);
+			adjust = nfsd->nd_dpos - mtod(mp, caddr_t);
 			mp->m_len -= adjust;
 			if (mp->m_len > 0 && adjust > 0)
 				mp->m_data += adjust;
@@ -906,10 +875,10 @@ nfsrv_write(struct nfsrv_descript *nfsd,
 	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
 	if (error)
 		goto bad;
-	if (info.nmi_v3)
+	if (v3)
 		forat_ret = VOP_GETATTR(vp, &forat, cred, procp);
 	if (vp->v_type != VREG) {
-		if (info.nmi_v3)
+		if (v3)
 			error = EINVAL;
 		else
 			error = (vp->v_type == VDIR) ? EISDIR : EACCES;
@@ -927,7 +896,7 @@ nfsrv_write(struct nfsrv_descript *nfsd,
 	    ivlen = cnt * sizeof(*ivp);
 	    uiop->uio_iov = iv = ivp;
 	    uiop->uio_iovcnt = cnt;
-	    mp = info.nmi_mrep;
+	    mp = nfsd->nd_mrep;
 	    while (mp) {
 		if (mp->m_len > 0) {
 			ivp->iov_base = mtod(mp, caddr_t);
@@ -956,17 +925,17 @@ nfsrv_write(struct nfsrv_descript *nfsd,
 	vput(vp);
 	if (!error)
 		error = aftat_ret;
-	if (nfsm_reply(&info, nfsd, slp, mrq, error,
-	    NFSX_PREOPATTR(info.nmi_v3) + NFSX_POSTOPORFATTR(info.nmi_v3) +
-	    2 * NFSX_UNSIGNED + NFSX_WRITEVERF(info.nmi_v3)) != 0)
+	if (nfsm_reply(nfsd, slp, mrq, &mb, error,
+	    NFSX_PREOPATTR(v3) + NFSX_POSTOPORFATTR(v3) +
+	    2 * NFSX_UNSIGNED + NFSX_WRITEVERF(v3)) != 0)
 		return 0;
-	if (info.nmi_v3) {
-		nfsm_srvwcc(nfsd, forat_ret, &forat, aftat_ret, &va, &info);
+	if (v3) {
+		nfsm_srvwcc(nfsd, forat_ret, &forat, aftat_ret, &va, &mb);
 		if (error) {
 			error = 0;
 			goto nfsmout;
 		}
-		tl = nfsm_build(&info.nmi_mb, 4 * NFSX_UNSIGNED);
+		tl = nfsm_build(&mb, 4 * NFSX_UNSIGNED);
 		*tl++ = txdr_unsigned(retlen);
 		if (stable == NFSV3WRITE_UNSTABLE)
 			*tl++ = txdr_unsigned(stable);
@@ -981,7 +950,7 @@ nfsrv_write(struct nfsrv_descript *nfsd,
 		*tl++ = txdr_unsigned(boottime.tv_sec);
 		*tl = txdr_unsigned(boottime.tv_usec);
 	} else {
-		fp = nfsm_build(&info.nmi_mb, NFSX_V2FATTR);
+		fp = nfsm_build(&mb, NFSX_V2FATTR);
 		nfsm_srvfattr(nfsd, &va, fp);
 	}
 nfsmout:
@@ -990,18 +959,18 @@ nfsmout:
 vbad:
 	vput(vp);
 bad:
-	if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0)
+	if (nfsm_reply(nfsd, slp, mrq, &mb, error, 0) != 0)
 		return 0;
-	nfsm_srvwcc(nfsd, forat_ret, &forat, aftat_ret, &va, &info);
+	nfsm_srvwcc(nfsd, forat_ret, &forat, aftat_ret, &va, &mb);
 	return (0);
 }
 
 static inline void
-nfsm_srvpostop_fh(struct nfsm_info *infop, fhandle_t *fhp)
+nfsm_srvpostop_fh(struct mbuf **mb, fhandle_t *fhp)
 {
 	uint32_t *tl;
 
-	tl = nfsm_build(&infop->nmi_mb, 2 * NFSX_UNSIGNED + NFSX_V3FH);
+	tl = nfsm_build(mb, 2 * NFSX_UNSIGNED + NFSX_V3FH);
 	*tl++ = nfs_true;
 	*tl++ = txdr_unsigned(NFSX_V3FH);
 	bcopy(fhp, tl, NFSX_V3FH);
@@ -1016,11 +985,11 @@ nfsrv_create(struct nfsrv_descript *nfsd
     struct proc *procp, struct mbuf **mrq)
 {
 	struct mbuf *nam = nfsd->nd_nam;
+	struct mbuf *mb;
 	struct ucred *cred = &nfsd->nd_cr;
 	struct nfs_fattr *fp;
 	struct vattr va, dirfor, diraft;
 	struct nfsv2_sattr *sp;
-	struct nfsm_info	info;
 	u_int32_t *tl;
 	struct nameidata nd;
 	caddr_t cp;
@@ -1032,22 +1001,18 @@ nfsrv_create(struct nfsrv_descript *nfsd
 	fhandle_t *fhp;
 	u_quad_t tempsize;
 	u_char cverf[NFSX_V3CREATEVERF];
+	int v3;
 
-	info.nmi_mreq = NULL;
-	info.nmi_mrep = nfsd->nd_mrep;
-	info.nmi_md = nfsd->nd_md;
-	info.nmi_dpos = nfsd->nd_dpos;
-	info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
-	info.nmi_errorp = &error;
+	v3 = (nfsd->nd_flag & ND_NFSV3);
 
-	if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+	if (nfsm_srvmtofh1(nfsd, slp, mrq, &mb, &error) != 0)
 		return 0;
 	else if (error != 0)
 		return error;
 	fhp = &nfh.fh_generic;
-	if (nfsm_srvmtofh2(&info, fhp) != 0)
+	if (nfsm_srvmtofh2(nfsd, fhp, &error) != 0)
 		return error;
-	if (nfsm_srvnamesiz(&info, &len) != 0)
+	if (nfsm_srvnamesiz(nfsd, &len, &error) != 0)
 		return error;
 	if (error) {
 		/*
@@ -1055,17 +1020,17 @@ nfsrv_create(struct nfsrv_descript *nfsd
 		 * from EBADRPC. But it does not make sense to continue
 		 * anyway if the error set in nfsm_srvnamesiz is NFSERR_NAMETOL.
 		 */
-		(void)nfsm_reply(&info, nfsd, slp, mrq, error, 0);
+		(void)nfsm_reply(nfsd, slp, mrq, &mb, error, 0);
 		return 0;
 	}
 
 	NDINIT(&nd, CREATE, LOCKPARENT | LOCKLEAF | SAVESTART, UIO_SYSSPACE,
 	    NULL, procp);
 	nd.ni_cnd.cn_cred = cred;
-	error = nfs_namei(&nd, fhp, len, slp, nam, &info.nmi_md,
-	    &info.nmi_dpos, &dirp, procp);
+	error = nfs_namei(&nd, fhp, len, slp, nam, &nfsd->nd_md,
+	    &nfsd->nd_dpos, &dirp, procp);
 	if (dirp) {
-		if (info.nmi_v3)
+		if (v3)
 			dirfor_ret = VOP_GETATTR(dirp, &dirfor, cred, procp);
 		else {
 			vrele(dirp);
@@ -1073,19 +1038,19 @@ nfsrv_create(struct nfsrv_descript *nfsd
 		}
 	}
 	if (error) {
-		if (nfsm_reply(&info, nfsd, slp, mrq, error,
-		    NFSX_WCCDATA(info.nmi_v3)) != 0)
+		if (nfsm_reply(nfsd, slp, mrq, &mb, error,
+		    NFSX_WCCDATA(v3)) != 0)
 			return 0;
 		nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
-		    &info);
+		    &mb);
 		if (dirp)
 			vrele(dirp);
 		return (0);
 	}
 
 	vattr_null(&va);
-	if (info.nmi_v3) {
-		tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+	if (v3) {
+		tl = (uint32_t *)nfsd_dissect(nfsd, NFSX_UNSIGNED, &error);
 		if (tl == NULL)
 			goto nfsmout;
 		how = fxdr_unsigned(int, *tl);
@@ -1096,13 +1061,12 @@ nfsrv_create(struct nfsrv_descript *nfsd
 				break;
 			}
 		case NFSV3CREATE_UNCHECKED:
-			error = nfsm_srvsattr(&info.nmi_md, &va, info.nmi_mrep,
-			    &info.nmi_dpos);
+			error = nfsm_srvsattr(nfsd, &va);
 			if (error)
 				goto nfsmout;
 			break;
 		case NFSV3CREATE_EXCLUSIVE:
-			cp = (caddr_t)nfsm_dissect(&info, NFSX_V3CREATEVERF);
+			cp = (caddr_t)nfsd_dissect(nfsd, NFSX_V3CREATEVERF, &error);
 			if (cp == NULL)
 				goto nfsmout;
 			bcopy(cp, cverf, NFSX_V3CREATEVERF);
@@ -1113,7 +1077,7 @@ nfsrv_create(struct nfsrv_descript *nfsd
 		}
 		va.va_type = VREG;
 	} else {
-		sp = (struct nfsv2_sattr *)nfsm_dissect(&info, NFSX_V2SATTR);
+		sp = (struct nfsv2_sattr *)nfsd_dissect(nfsd, NFSX_V2SATTR, &error);
 		if (sp == NULL)
 			goto nfsmout;
 		va.va_type = IFTOVT(fxdr_unsigned(u_int32_t, sp->sa_mode));
@@ -1171,7 +1135,7 @@ nfsrv_create(struct nfsrv_descript *nfsd
 				}
 				VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
 				vput(nd.ni_dvp);
-				if (nfsm_reply(&info, nfsd, slp, mrq, error,
+				if (nfsm_reply(nfsd, slp, mrq, &mb, error,
 				    0) != 0)
 					return 0;
 				error = 0;
@@ -1187,7 +1151,7 @@ nfsrv_create(struct nfsrv_descript *nfsd
 					pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
 					nd.ni_cnd.cn_flags &= ~HASBUF;
 				}
-				if (nfsm_reply(&info, nfsd, slp, mrq, error,
+				if (nfsm_reply(nfsd, slp, mrq, &mb, error,
 				    0) != 0)
 					return 0;
 				error = 0;
@@ -1202,7 +1166,7 @@ nfsrv_create(struct nfsrv_descript *nfsd
 					pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
 					nd.ni_cnd.cn_flags &= ~HASBUF;
 				}
-				if (nfsm_reply(&info, nfsd, slp, mrq, error,
+				if (nfsm_reply(nfsd, slp, mrq, &mb, error,
 				    0) != 0)
 					return 0;
 				error = 0;
@@ -1215,7 +1179,7 @@ nfsrv_create(struct nfsrv_descript *nfsd
 				vput(nd.ni_vp);
 				VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
 				error = EINVAL;
-				if (nfsm_reply(&info, nfsd, slp, mrq, error,
+				if (nfsm_reply(nfsd, slp, mrq, &mb, error,
 				    0) != 0)
 					return 0;
 				error = 0;
@@ -1262,26 +1226,26 @@ nfsrv_create(struct nfsrv_descript *nfsd
 			error = VOP_GETATTR(vp, &va, cred, procp);
 		vput(vp);
 	}
-	if (info.nmi_v3) {
+	if (v3) {
 		if (exclusive_flag && !error &&
 			bcmp(cverf, (caddr_t)&va.va_atime, NFSX_V3CREATEVERF))
 			error = EEXIST;
 		diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp);
 		vrele(dirp);
 	}
-	if (nfsm_reply(&info, nfsd, slp, mrq, error, NFSX_SRVFH(info.nmi_v3) +
-	    NFSX_FATTR(info.nmi_v3) + NFSX_WCCDATA(info.nmi_v3)) != 0)
+	if (nfsm_reply(nfsd, slp, mrq, &mb, error,
+	    NFSX_SRVFH(v3) + NFSX_FATTR(v3) + NFSX_WCCDATA(v3)) != 0)
 		return 0;
-	if (info.nmi_v3) {
+	if (v3) {
 		if (!error) {
-			nfsm_srvpostop_fh(&info, fhp);
-			nfsm_srvpostop_attr(nfsd, 0, &va, &info);
+			nfsm_srvpostop_fh(&mb, fhp);
+			nfsm_srvpostop_attr(nfsd, 0, &va, &mb);
 		}
 		nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
-		    &info);
+		    &mb);
 	} else {
-		nfsm_srvfhtom(&info.nmi_mb, fhp, info.nmi_v3);
-		fp = nfsm_build(&info.nmi_mb, NFSX_V2FATTR);
+		nfsm_srvfhtom(&mb, fhp, v3);
+		fp = nfsm_build(&mb, NFSX_V2FATTR);
 		nfsm_srvfattr(nfsd, &va, fp);
 	}
 	return (0);
@@ -1313,9 +1277,9 @@ nfsrv_mknod(struct nfsrv_descript *nfsd,
     struct proc *procp, struct mbuf **mrq)
 {
 	struct mbuf *nam = nfsd->nd_nam;
+	struct mbuf *mb;
 	struct ucred *cred = &nfsd->nd_cr;
 	struct vattr va, dirfor, diraft;
-	struct nfsm_info	info;
 	u_int32_t *tl;
 	struct nameidata nd;
 	int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
@@ -1325,21 +1289,14 @@ nfsrv_mknod(struct nfsrv_descript *nfsd,
 	nfsfh_t nfh;
 	fhandle_t *fhp;
 
-	info.nmi_mreq = NULL;
-	info.nmi_mrep = nfsd->nd_mrep;
-	info.nmi_md = nfsd->nd_md;
-	info.nmi_dpos = nfsd->nd_dpos;
-	info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
-	info.nmi_errorp = &error;
-
-	if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+	if (nfsm_srvmtofh1(nfsd, slp, mrq, &mb, &error) != 0)
 		return 0;
 	else if (error != 0)
 		return error;
 	fhp = &nfh.fh_generic;
-	if (nfsm_srvmtofh2(&info, fhp) != 0)
+	if (nfsm_srvmtofh2(nfsd, fhp, &error) != 0)
 		return error;
-	if (nfsm_srvnamesiz(&info, &len) != 0)
+	if (nfsm_srvnamesiz(nfsd, &len, &error) != 0)
 		return error;
 	if (error) {
 		/*
@@ -1347,28 +1304,28 @@ nfsrv_mknod(struct nfsrv_descript *nfsd,
 		 * from EBADRPC. But it does not make sense to continue
 		 * anyway if the error set in nfsm_srvnamesiz is NFSERR_NAMETOL.
 		 */
-		(void)nfsm_reply(&info, nfsd, slp, mrq, error, 0);
+		(void)nfsm_reply(nfsd, slp, mrq, &mb, error, 0);
 		return 0;
 	}
 
 	NDINIT(&nd, CREATE, LOCKPARENT | LOCKLEAF | SAVESTART, UIO_SYSSPACE,
 	    NULL, procp);
 	nd.ni_cnd.cn_cred = cred;
-	error = nfs_namei(&nd, fhp, len, slp, nam, &info.nmi_md, &info.nmi_dpos, &dirp, procp);
+	error = nfs_namei(&nd, fhp, len, slp, nam, &nfsd->nd_md, &nfsd->nd_dpos, &dirp, procp);
 	if (dirp)
 		dirfor_ret = VOP_GETATTR(dirp, &dirfor, cred, procp);
 	if (error) {
-		if (nfsm_reply(&info, nfsd, slp, mrq, error,
+		if (nfsm_reply(nfsd, slp, mrq, &mb, error,
 		    NFSX_WCCDATA(1)) != 0)
 			return 0;
 		nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
-		    &info);
+		    &mb);
 		if (dirp)
 			vrele(dirp);
 		return (0);
 	}
 
-	tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+	tl = (uint32_t *)nfsd_dissect(nfsd, NFSX_UNSIGNED, &error);
 	if (tl == NULL)
 		goto nfsmout;
 	vtyp = nfsv3tov_type(*tl);
@@ -1386,11 +1343,11 @@ nfsrv_mknod(struct nfsrv_descript *nfsd,
 		goto out;
 	}
 	vattr_null(&va);
-	error = nfsm_srvsattr(&info.nmi_md, &va, info.nmi_mrep, &info.nmi_dpos);
+	error = nfsm_srvsattr(nfsd, &va);
 	if (error)
 		goto nfsmout;
 	if (vtyp == VCHR || vtyp == VBLK) {
-		tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED);
+		tl = (uint32_t *)nfsd_dissect(nfsd, 2 * NFSX_UNSIGNED, &error);
 		if (tl == NULL)
 			goto nfsmout;
 		major = fxdr_unsigned(u_int32_t, *tl++);
@@ -1462,14 +1419,14 @@ out:
 	}
 	diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp);
 	vrele(dirp);
-	if (nfsm_reply(&info, nfsd, slp, mrq, error,
+	if (nfsm_reply(nfsd, slp, mrq, &mb, error,
 	    NFSX_SRVFH(1) + NFSX_POSTOPATTR(1) + NFSX_WCCDATA(1)) != 0)
 		return 0;
 	if (!error) {
-		nfsm_srvpostop_fh(&info, fhp);
-		nfsm_srvpostop_attr(nfsd, 0, &va, &info);
+		nfsm_srvpostop_fh(&mb, fhp);
+		nfsm_srvpostop_attr(nfsd, 0, &va, &mb);
 	}
-	nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft, &info);
+	nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft, &mb);
 	return (0);
 nfsmout:
 	if (dirp)
@@ -1496,32 +1453,27 @@ nfsrv_remove(struct nfsrv_descript *nfsd
     struct proc *procp, struct mbuf **mrq)
 {
 	struct mbuf *nam = nfsd->nd_nam;
+	struct mbuf *mb;
 	struct ucred *cred = &nfsd->nd_cr;
 	struct nameidata nd;
-	struct nfsm_info	info;
 	int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
 	struct vnode *vp, *dirp;
 	struct vattr dirfor, diraft;
 	nfsfh_t nfh;
 	fhandle_t *fhp;
+	int v3;
 
-	info.nmi_mreq = NULL;
-	info.nmi_mrep = nfsd->nd_mrep;
-	info.nmi_md = nfsd->nd_md;
-	info.nmi_dpos = nfsd->nd_dpos;
-	info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
-	info.nmi_errorp = &error;
-
+	v3 = (nfsd->nd_flag & ND_NFSV3);
 	vp = NULL;
 
-	if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+	if (nfsm_srvmtofh1(nfsd, slp, mrq, &mb, &error) != 0)
 		return 0;
 	else if (error != 0)
 		goto nfsmout;
 	fhp = &nfh.fh_generic;
-	if (nfsm_srvmtofh2(&info, fhp) != 0)
+	if (nfsm_srvmtofh2(nfsd, fhp, &error) != 0)
 		goto nfsmout;
-	if (nfsm_srvnamesiz(&info, &len) != 0)
+	if (nfsm_srvnamesiz(nfsd, &len, &error) != 0)
 		goto nfsmout;
 	if (error) {
 		/*
@@ -1529,15 +1481,15 @@ nfsrv_remove(struct nfsrv_descript *nfsd
 		 * from EBADRPC. But it does not make sense to continue
 		 * anyway if the error set in nfsm_srvnamesiz is NFSERR_NAMETOL.
 		 */
-		(void)nfsm_reply(&info, nfsd, slp, mrq, error, 0);
+		(void)nfsm_reply(nfsd, slp, mrq, &mb, error, 0);
 		return 0;
 	}
 
  	NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_SYSSPACE, NULL, procp);
 	nd.ni_cnd.cn_cred = cred;
-	error = nfs_namei(&nd, fhp, len, slp, nam, &info.nmi_md, &info.nmi_dpos, &dirp, procp);
+	error = nfs_namei(&nd, fhp, len, slp, nam, &nfsd->nd_md, &nfsd->nd_dpos, &dirp, procp);
 	if (dirp) {
-		if (info.nmi_v3)
+		if (v3)
 			dirfor_ret = VOP_GETATTR(dirp, &dirfor, cred, procp);
 		else {
 			vrele(dirp);
@@ -1571,16 +1523,15 @@ out:
 			vput(vp);
 		}
 	}
-	if (dirp && info.nmi_v3) {
+	if (dirp && v3) {
 		diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp);
 		vrele(dirp);
 	}
-	if (nfsm_reply(&info, nfsd, slp, mrq, error,
-	    NFSX_WCCDATA(info.nmi_v3)) != 0)
+	if (nfsm_reply(nfsd, slp, mrq, &mb, error, NFSX_WCCDATA(v3)) != 0)
 		return 0;
-	if (info.nmi_v3) {
+	if (v3) {
 		nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
-		    &info);
+		    &mb);
 		return (0);
 	}
 
@@ -1596,8 +1547,8 @@ nfsrv_rename(struct nfsrv_descript *nfsd
     struct proc *procp, struct mbuf **mrq)
 {
 	struct mbuf *nam = nfsd->nd_nam;
+	struct mbuf *mb;
 	struct ucred *cred = &nfsd->nd_cr;
-	struct nfsm_info	info;
 	int error = 0, len, len2, fdirfor_ret = 1, fdiraft_ret = 1;
 	int tdirfor_ret = 1, tdiraft_ret = 1;
 	struct nameidata fromnd, tond;
@@ -1607,22 +1558,18 @@ nfsrv_rename(struct nfsrv_descript *nfsd
 	nfsfh_t fnfh, tnfh;
 	fhandle_t *ffhp, *tfhp;
 	uid_t saved_uid;
+	int v3;
 
-	info.nmi_mreq = NULL;
-	info.nmi_mrep = nfsd->nd_mrep;
-	info.nmi_md = nfsd->nd_md;
-	info.nmi_dpos = nfsd->nd_dpos;
-	info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
-	info.nmi_errorp = &error;
+	v3 = (nfsd->nd_flag & ND_NFSV3);
 
-	if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+	if (nfsm_srvmtofh1(nfsd, slp, mrq, &mb, &error) != 0)
 		return 0;
 	else if (error != 0)
 		return error;
 	ffhp = &fnfh.fh_generic;
-	if (nfsm_srvmtofh2(&info, ffhp) != 0)
+	if (nfsm_srvmtofh2(nfsd, ffhp, &error) != 0)
 		return error;
-	if (nfsm_srvnamesiz(&info, &len) != 0)
+	if (nfsm_srvnamesiz(nfsd, &len, &error) != 0)
 		return error;
 	if (error) {
 		/*
@@ -1630,7 +1577,7 @@ nfsrv_rename(struct nfsrv_descript *nfsd
 		 * from EBADRPC. But it does not make sense to continue
 		 * anyway if the error set in nfsm_srvnamesiz is NFSERR_NAMETOL.
 		 */
-		(void)nfsm_reply(&info, nfsd, slp, mrq, error, 0);
+		(void)nfsm_reply(nfsd, slp, mrq, &mb, error, 0);
 		return 0;
 	}
 
@@ -1643,10 +1590,10 @@ nfsrv_rename(struct nfsrv_descript *nfsd
 	NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART, UIO_SYSSPACE, NULL,
 	    procp);
 	fromnd.ni_cnd.cn_cred = cred;
-	error = nfs_namei(&fromnd, ffhp, len, slp, nam, &info.nmi_md,
-	    &info.nmi_dpos, &fdirp, procp);
+	error = nfs_namei(&fromnd, ffhp, len, slp, nam, &nfsd->nd_md,
+	    &nfsd->nd_dpos, &fdirp, procp);
 	if (fdirp) {
-		if (info.nmi_v3)
+		if (v3)
 			fdirfor_ret = VOP_GETATTR(fdirp, &fdirfor, cred,
 				procp);
 		else {
@@ -1655,39 +1602,39 @@ nfsrv_rename(struct nfsrv_descript *nfsd
 		}
 	}
 	if (error) {
-		if (nfsm_reply(&info, nfsd, slp, mrq, error,
-		    2 * NFSX_WCCDATA(info.nmi_v3)) != 0)
+		if (nfsm_reply(nfsd, slp, mrq, &mb, error,
+		    2 * NFSX_WCCDATA(v3)) != 0)
 			return 0;
 		nfsm_srvwcc(nfsd, fdirfor_ret, &fdirfor, fdiraft_ret, &fdiraft,
-		    &info);
+		    &mb);
 		nfsm_srvwcc(nfsd, tdirfor_ret, &tdirfor, tdiraft_ret, &tdiraft,
-		    &info);
+		    &mb);
 		if (fdirp)
 			vrele(fdirp);
 		return (0);
 	}
 
 	fvp = fromnd.ni_vp;
-	if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
-		return 0;
-	else if (error != 0)
+	if (nfsm_srvmtofh1(nfsd, slp, mrq, &mb, &error) != 0) {
+		error = 0;
+		goto nfsmout;
+	} else if (error != 0)
 		goto nfsmout;
 	tfhp = &tnfh.fh_generic;
-	if (nfsm_srvmtofh2(&info, tfhp) != 0)
+	if (nfsm_srvmtofh2(nfsd, tfhp, &error) != 0)
 		goto nfsmout;
-	if (nfsm_strsiz(&info, &len2, NFS_MAXNAMLEN) != 0)
+	if (nfsd_strsiz(nfsd, &len2, NFS_MAXNAMLEN, &error) != 0)
 		goto nfsmout;
 	cred->cr_uid = saved_uid;
 
 	NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF| NOCACHE | SAVESTART,
 	    UIO_SYSSPACE, NULL, procp);
 	tond.ni_cnd.cn_cred = cred;
-	error = nfs_namei(&tond, tfhp, len2, slp, nam, &info.nmi_md,
-	    &info.nmi_dpos, &tdirp, procp);
+	error = nfs_namei(&tond, tfhp, len2, slp, nam, &nfsd->nd_md,
+	    &nfsd->nd_dpos, &tdirp, procp);
 	if (tdirp) {
-		if (info.nmi_v3)
-			tdirfor_ret = VOP_GETATTR(tdirp, &tdirfor, cred,
-				procp);
+		if (v3)
+			tdirfor_ret = VOP_GETATTR(tdirp, &tdirfor, cred, procp);
 		else {
 			vrele(tdirp);
 			tdirp = NULL;
@@ -1703,27 +1650,27 @@ nfsrv_rename(struct nfsrv_descript *nfsd
 	tvp = tond.ni_vp;
 	if (tvp != NULL) {
 		if (fvp->v_type == VDIR && tvp->v_type != VDIR) {
-			error = info.nmi_v3 ? EEXIST : EISDIR;
+			error = v3 ? EEXIST : EISDIR;
 			goto out;
 		} else if (fvp->v_type != VDIR && tvp->v_type == VDIR) {
-			error = info.nmi_v3 ? EEXIST : ENOTDIR;
+			error = v3 ? EEXIST : ENOTDIR;
 			goto out;
 		}
 		if (tvp->v_type == VDIR && tvp->v_mountedhere) {
-			error = info.nmi_v3 ? EXDEV : ENOTEMPTY;
+			error = v3 ? EXDEV : ENOTEMPTY;
 			goto out;
 		}
 	}
 	if (fvp->v_type == VDIR && fvp->v_mountedhere) {
-		error = info.nmi_v3 ? EXDEV : ENOTEMPTY;
+		error = v3 ? EXDEV : ENOTEMPTY;
 		goto out;
 	}
 	if (fvp->v_mount != tdvp->v_mount) {
-		error = info.nmi_v3 ? EXDEV : ENOTEMPTY;
+		error = v3 ? EXDEV : ENOTEMPTY;
 		goto out;
 	}
 	if (fvp == tdvp)
-		error = info.nmi_v3 ? EINVAL : ENOTEMPTY;
+		error = v3 ? EINVAL : ENOTEMPTY;
 	/*
 	 * If source is the same as the destination (that is the
 	 * same vnode with the same name in the same directory),
@@ -1768,14 +1715,13 @@ out1:
 	}
 	vrele(fromnd.ni_startdir);
 	pool_put(&namei_pool, fromnd.ni_cnd.cn_pnbuf);
-	if (nfsm_reply(&info, nfsd, slp, mrq, error,
-	    2 * NFSX_WCCDATA(info.nmi_v3)) != 0)
+	if (nfsm_reply(nfsd, slp, mrq, &mb, error, 2 * NFSX_WCCDATA(v3)) != 0)
 		return 0;
-	if (info.nmi_v3) {
+	if (v3) {
 		nfsm_srvwcc(nfsd, fdirfor_ret, &fdirfor, fdiraft_ret, &fdiraft,
-		    &info);
+		    &mb);
 		nfsm_srvwcc(nfsd, tdirfor_ret, &tdirfor, tdiraft_ret, &tdiraft,
-		    &info);
+		    &mb);
 	}
 	return (0);
 
@@ -1807,7 +1753,7 @@ nfsrv_link(struct nfsrv_descript *nfsd, 
     struct proc *procp, struct mbuf **mrq)
 {
 	struct mbuf *nam = nfsd->nd_nam;
-	struct nfsm_info	info;
+	struct mbuf *mb;
 	struct ucred *cred = &nfsd->nd_cr;
 	struct nameidata nd;
 	int error = 0, rdonly, len, dirfor_ret = 1, diraft_ret = 1;
@@ -1816,29 +1762,25 @@ nfsrv_link(struct nfsrv_descript *nfsd, 
 	struct vattr dirfor, diraft, at;
 	nfsfh_t nfh, dnfh;
 	fhandle_t *fhp, *dfhp;
+	int v3;
 
-	info.nmi_mreq = NULL;
-	info.nmi_mrep = nfsd->nd_mrep;
-	info.nmi_md = nfsd->nd_md;
-	info.nmi_dpos = nfsd->nd_dpos;
-	info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
-	info.nmi_errorp = &error;
+	v3 = (nfsd->nd_flag & ND_NFSV3);
 
-	if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+	if (nfsm_srvmtofh1(nfsd, slp, mrq, &mb, &error) != 0)
 		return 0;
 	else if (error != 0)
 		goto nfsmout;
 	fhp = &nfh.fh_generic;
-	if (nfsm_srvmtofh2(&info, fhp) != 0)
+	if (nfsm_srvmtofh2(nfsd, fhp, &error) != 0)
 		goto nfsmout;
-	if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+	if (nfsm_srvmtofh1(nfsd, slp, mrq, &mb, &error) != 0)
 		return 0;
 	else if (error != 0)
 		goto nfsmout;
 	dfhp = &dnfh.fh_generic;
-	if (nfsm_srvmtofh2(&info, dfhp) != 0)
+	if (nfsm_srvmtofh2(nfsd, dfhp, &error) != 0)
 		goto nfsmout;
-	if (nfsm_srvnamesiz(&info, &len) != 0)
+	if (nfsm_srvnamesiz(nfsd, &len, &error) != 0)
 		goto nfsmout;
 	if (error) {
 		/*
@@ -1846,19 +1788,18 @@ nfsrv_link(struct nfsrv_descript *nfsd, 
 		 * from EBADRPC. But it does not make sense to continue
 		 * anyway if the error set in nfsm_srvnamesiz is NFSERR_NAMETOL.
 		 */
-		(void)nfsm_reply(&info, nfsd, slp, mrq, error, 0);
+		(void)nfsm_reply(nfsd, slp, mrq, &mb, error, 0);
 		return 0;
 	}
 
 	error = nfsrv_fhtovp(fhp, 0, &vp, cred, slp, nam, &rdonly);
 	if (error) {
-		if (nfsm_reply(&info, nfsd, slp, mrq, error,
-		    NFSX_POSTOPATTR(info.nmi_v3) +
-		    NFSX_WCCDATA(info.nmi_v3)) != 0)
+		if (nfsm_reply(nfsd, slp, mrq, &mb, error,
+		    NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3)) != 0)
 			return 0;
-		nfsm_srvpostop_attr(nfsd, getret, &at, &info);
+		nfsm_srvpostop_attr(nfsd, getret, &at, &mb);
 		nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
-		    &info);
+		    &mb);
 		error = 0;
 		goto nfsmout;
 	}
@@ -1867,12 +1808,11 @@ nfsrv_link(struct nfsrv_descript *nfsd, 
 
 	NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, NULL, procp);
 	nd.ni_cnd.cn_cred = cred;
-	error = nfs_namei(&nd, dfhp, len, slp, nam, &info.nmi_md,
-	    &info.nmi_dpos, &dirp, procp);
+	error = nfs_namei(&nd, dfhp, len, slp, nam, &nfsd->nd_md,
+	    &nfsd->nd_dpos, &dirp, procp);
 	if (dirp) {
-		if (info.nmi_v3)
-			dirfor_ret = VOP_GETATTR(dirp, &dirfor, cred,
-				procp);
+		if (v3)
+			dirfor_ret = VOP_GETATTR(dirp, &dirfor, cred, procp);
 		else {
 			vrele(dirp);
 			dirp = NULL;
@@ -1901,20 +1841,20 @@ out:
 			vrele(nd.ni_vp);
 	}
 out1:
-	if (info.nmi_v3)
+	if (v3)
 		getret = VOP_GETATTR(vp, &at, cred, procp);
 	if (dirp) {
 		diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp);
 		vrele(dirp);
 	}
 	vrele(vp);
-	if (nfsm_reply(&info, nfsd, slp, mrq, error,
-	    NFSX_POSTOPATTR(info.nmi_v3) + NFSX_WCCDATA(info.nmi_v3)) != 0)
+	if (nfsm_reply(nfsd, slp, mrq, &mb, error,
+	    NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3)) != 0)
 		return 0;
-	if (info.nmi_v3) {
-		nfsm_srvpostop_attr(nfsd, getret, &at, &info);
+	if (v3) {
+		nfsm_srvpostop_attr(nfsd, getret, &at, &mb);
 		nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
-		     &info);
+		     &mb);
 		error = 0;
 	}
 nfsmout:
@@ -1929,10 +1869,10 @@ nfsrv_symlink(struct nfsrv_descript *nfs
     struct proc *procp, struct mbuf **mrq)
 {
 	struct mbuf *nam = nfsd->nd_nam;
+	struct mbuf *mb;
 	struct ucred *cred = &nfsd->nd_cr;
 	struct vattr va, dirfor, diraft;
 	struct nameidata nd;
-	struct nfsm_info	info;
 	struct nfsv2_sattr *sp;
 	char *pathcp = NULL;
 	struct uio io;
@@ -1941,22 +1881,18 @@ nfsrv_symlink(struct nfsrv_descript *nfs
 	struct vnode *dirp = NULL;
 	nfsfh_t nfh;
 	fhandle_t *fhp;
+	int v3;
 
-	info.nmi_mreq = NULL;
-	info.nmi_mrep = nfsd->nd_mrep;
-	info.nmi_md = nfsd->nd_md;
-	info.nmi_dpos = nfsd->nd_dpos;
-	info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
-	info.nmi_errorp = &error;
+	v3 = (nfsd->nd_flag & ND_NFSV3);
 
-	if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+	if (nfsm_srvmtofh1(nfsd, slp, mrq, &mb, &error) != 0)
 		return 0;
 	else if (error != 0)
 		return error;
 	fhp = &nfh.fh_generic;
-	if (nfsm_srvmtofh2(&info, fhp) != 0)
+	if (nfsm_srvmtofh2(nfsd, fhp, &error) != 0)
 		return error;
-	if (nfsm_srvnamesiz(&info, &len) != 0)
+	if (nfsm_srvnamesiz(nfsd, &len, &error) != 0)
 		return error;
 	if (error) {
 		/*
@@ -1964,16 +1900,16 @@ nfsrv_symlink(struct nfsrv_descript *nfs
 		 * from EBADRPC. But it does not make sense to continue
 		 * anyway if the error set in nfsm_srvnamesiz is NFSERR_NAMETOL.
 		 */
-		(void)nfsm_reply(&info, nfsd, slp, mrq, error, 0);
+		(void)nfsm_reply(nfsd, slp, mrq, &mb, error, 0);
 		return 0;
 	}
 
 	NDINIT(&nd, CREATE, LOCKPARENT | SAVESTART, UIO_SYSSPACE, NULL, procp);
 	nd.ni_cnd.cn_cred = cred;
-	error = nfs_namei(&nd, fhp, len, slp, nam, &info.nmi_md,
-	    &info.nmi_dpos, &dirp, procp);
+	error = nfs_namei(&nd, fhp, len, slp, nam, &nfsd->nd_md,
+	    &nfsd->nd_dpos, &dirp, procp);
 	if (dirp) {
-		if (info.nmi_v3)
+		if (v3)
 			dirfor_ret = VOP_GETATTR(dirp, &dirfor, cred,
 				procp);
 		else {
@@ -1984,13 +1920,12 @@ nfsrv_symlink(struct nfsrv_descript *nfs
 	if (error)
 		goto out;
 	vattr_null(&va);
-	if (info.nmi_v3) {
-		error = nfsm_srvsattr(&info.nmi_md, &va, info.nmi_mrep,
-		    &info.nmi_dpos);
+	if (v3) {
+		error = nfsm_srvsattr(nfsd, &va);
 		if (error)
 			goto nfsmout;
 	}
-	if (nfsm_strsiz(&info, &len2, NFS_MAXPATHLEN) != 0)
+	if (nfsd_strsiz(nfsd, &len2, NFS_MAXPATHLEN, &error) != 0)
 		goto nfsmout;
 	pathlen = len2 + 1;
 	pathcp = malloc(pathlen, M_TEMP, M_WAITOK);
@@ -2003,10 +1938,10 @@ nfsrv_symlink(struct nfsrv_descript *nfs
 	io.uio_segflg = UIO_SYSSPACE;
 	io.uio_rw = UIO_READ;
 	io.uio_procp = NULL;
-	if (nfsm_mtouio(&info, &io, len2) != 0)
+	if (nfsd_mtouio(nfsd, &io, len2, &error) != 0)
 		goto nfsmout;
-	if (!info.nmi_v3) {
-		sp = (struct nfsv2_sattr *)nfsm_dissect(&info, NFSX_V2SATTR);
+	if (!v3) {
+		sp = (struct nfsv2_sattr *)nfsd_dissect(nfsd, NFSX_V2SATTR, &error);
 		if (sp == NULL)
 			goto nfsmout;
 		va.va_mode = nfstov_mode(sp->sa_mode);
@@ -2028,7 +1963,7 @@ nfsrv_symlink(struct nfsrv_descript *nfs
 	if (error)
 		vrele(nd.ni_startdir);
 	else {
-		if (info.nmi_v3) {
+		if (v3) {
 			nd.ni_cnd.cn_nameiop = LOOKUP;
 			nd.ni_cnd.cn_flags &= ~(LOCKPARENT | SAVESTART |
 			    FOLLOW);
@@ -2057,16 +1992,16 @@ out:
 		diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp);
 		vrele(dirp);
 	}
-	if (nfsm_reply(&info, nfsd, slp, mrq, error, NFSX_SRVFH(info.nmi_v3) +
-	    NFSX_POSTOPATTR(info.nmi_v3) + NFSX_WCCDATA(info.nmi_v3)) != 0)
+	if (nfsm_reply(nfsd, slp, mrq, &mb, error,
+	    NFSX_SRVFH(v3) + NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3)) != 0)
 		return 0;
-	if (info.nmi_v3) {
+	if (v3) {
 		if (!error) {
-			nfsm_srvpostop_fh(&info, fhp);
-			nfsm_srvpostop_attr(nfsd, 0, &va, &info);
+			nfsm_srvpostop_fh(&mb, fhp);
+			nfsm_srvpostop_attr(nfsd, 0, &va, &mb);
 		}
 		nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
-		    &info);
+		    &mb);
 	}
 	return (0);
 nfsmout:
@@ -2096,32 +2031,28 @@ nfsrv_mkdir(struct nfsrv_descript *nfsd,
     struct proc *procp, struct mbuf **mrq)
 {
 	struct mbuf *nam = nfsd->nd_nam;
+	struct mbuf *mb;
 	struct ucred *cred = &nfsd->nd_cr;
 	struct vattr va, dirfor, diraft;
 	struct nfs_fattr *fp;
 	struct nameidata nd;
-	struct nfsm_info	info;
 	u_int32_t *tl;
 	int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
 	struct vnode *vp, *dirp = NULL;
 	nfsfh_t nfh;
 	fhandle_t *fhp;
+	int v3;
 
-	info.nmi_mreq = NULL;
-	info.nmi_mrep = nfsd->nd_mrep;
-	info.nmi_md = nfsd->nd_md;
-	info.nmi_dpos = nfsd->nd_dpos;
-	info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
-	info.nmi_errorp = &error;
+	v3 = (nfsd->nd_flag & ND_NFSV3);
 
-	if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+	if (nfsm_srvmtofh1(nfsd, slp, mrq, &mb, &error) != 0)
 		return 0;
 	else if (error != 0)
 		return error;
 	fhp = &nfh.fh_generic;
-	if (nfsm_srvmtofh2(&info, fhp) != 0)
+	if (nfsm_srvmtofh2(nfsd, fhp, &error) != 0)
 		return error;
-	if (nfsm_srvnamesiz(&info, &len) != 0)
+	if (nfsm_srvnamesiz(nfsd, &len, &error) != 0)
 		return error;
 	if (error) {
 		/*
@@ -2129,16 +2060,16 @@ nfsrv_mkdir(struct nfsrv_descript *nfsd,
 		 * from EBADRPC. But it does not make sense to continue
 		 * anyway if the error set in nfsm_srvnamesiz is NFSERR_NAMETOL.
 		 */
-		(void)nfsm_reply(&info, nfsd, slp, mrq, error, 0);
+		(void)nfsm_reply(nfsd, slp, mrq, &mb, error, 0);
 		return 0;
 	}
 
 	NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, NULL, procp);
 	nd.ni_cnd.cn_cred = cred;
-	error = nfs_namei(&nd, fhp, len, slp, nam, &info.nmi_md,
-	    &info.nmi_dpos, &dirp, procp);
+	error = nfs_namei(&nd, fhp, len, slp, nam, &nfsd->nd_md,
+	    &nfsd->nd_dpos, &dirp, procp);
 	if (dirp) {
-		if (info.nmi_v3)
+		if (v3)
 			dirfor_ret = VOP_GETATTR(dirp, &dirfor, cred, procp);
 		else {
 			vrele(dirp);
@@ -2146,24 +2077,23 @@ nfsrv_mkdir(struct nfsrv_descript *nfsd,
 		}
 	}
 	if (error) {
-		if (nfsm_reply(&info, nfsd, slp, mrq, error,
-		    NFSX_WCCDATA(info.nmi_v3)) != 0)
+		if (nfsm_reply(nfsd, slp, mrq, &mb, error,
+		    NFSX_WCCDATA(v3)) != 0)
 			return 0;
 		nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
-		    &info);
+		    &mb);
 		if (dirp)
 			vrele(dirp);
 		return (0);
 	}
 
 	vattr_null(&va);
-	if (info.nmi_v3) {
-		error = nfsm_srvsattr(&info.nmi_md, &va, info.nmi_mrep,
-		    &info.nmi_dpos);
+	if (v3) {
+		error = nfsm_srvsattr(nfsd, &va);
 		if (error)
 			goto nfsmout;
 	} else {
-		tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+		tl = (uint32_t *)nfsd_dissect(nfsd, NFSX_UNSIGNED, &error);
 		if (tl == NULL)
 			goto nfsmout;
 		va.va_mode = nfstov_mode(*tl++);
@@ -2195,19 +2125,19 @@ out:
 		diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp);
 		vrele(dirp);
 	}
-	if (nfsm_reply(&info, nfsd, slp, mrq, error, NFSX_SRVFH(info.nmi_v3) +
-	    NFSX_POSTOPATTR(info.nmi_v3) + NFSX_WCCDATA(info.nmi_v3)) != 0)
+	if (nfsm_reply(nfsd, slp, mrq, &mb, error,
+	    NFSX_SRVFH(v3) + NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3)) != 0)
 		return 0;
-	if (info.nmi_v3) {
+	if (v3) {
 		if (!error) {
-			nfsm_srvpostop_fh(&info, fhp);
-			nfsm_srvpostop_attr(nfsd, 0, &va, &info);
+			nfsm_srvpostop_fh(&mb, fhp);
+			nfsm_srvpostop_attr(nfsd, 0, &va, &mb);
 		}
 		nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
-		    &info);
+		    &mb);
 	} else {
-		nfsm_srvfhtom(&info.nmi_mb, fhp, info.nmi_v3);
-		fp = nfsm_build(&info.nmi_mb, NFSX_V2FATTR);
+		nfsm_srvfhtom(&mb, fhp, v3);
+		fp = nfsm_build(&mb, NFSX_V2FATTR);
 		nfsm_srvfattr(nfsd, &va, fp);
 	}
 	return (0);
@@ -2232,30 +2162,26 @@ nfsrv_rmdir(struct nfsrv_descript *nfsd,
     struct proc *procp, struct mbuf **mrq)
 {
 	struct mbuf *nam = nfsd->nd_nam;
+	struct mbuf *mb;
 	struct ucred *cred = &nfsd->nd_cr;
-	struct nfsm_info	info;
 	int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
 	struct vnode *vp, *dirp = NULL;
 	struct vattr dirfor, diraft;
 	nfsfh_t nfh;
 	fhandle_t *fhp;
 	struct nameidata nd;
+	int v3;
 
-	info.nmi_mreq = NULL;
-	info.nmi_mrep = nfsd->nd_mrep;
-	info.nmi_md = nfsd->nd_md;
-	info.nmi_dpos = nfsd->nd_dpos;
-	info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
-	info.nmi_errorp = &error;
+	v3 = (nfsd->nd_flag & ND_NFSV3);
 
-	if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+	if (nfsm_srvmtofh1(nfsd, slp, mrq, &mb, &error) != 0)
 		return 0;
 	else if (error != 0)
 		goto nfsmout;
 	fhp = &nfh.fh_generic;
-	if (nfsm_srvmtofh2(&info, fhp) != 0)
+	if (nfsm_srvmtofh2(nfsd, fhp, &error) != 0)
 		goto nfsmout;
-	if (nfsm_srvnamesiz(&info, &len) != 0)
+	if (nfsm_srvnamesiz(nfsd, &len, &error) != 0)
 		goto nfsmout;
 	if (error) {
 		/*
@@ -2263,16 +2189,16 @@ nfsrv_rmdir(struct nfsrv_descript *nfsd,
 		 * from EBADRPC. But it does not make sense to continue
 		 * anyway if the error set in nfsm_srvnamesiz is NFSERR_NAMETOL.
 		 */
-		(void)nfsm_reply(&info, nfsd, slp, mrq, error, 0);
+		(void)nfsm_reply(nfsd, slp, mrq, &mb, error, 0);
 		return 0;
 	}
 
 	NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_SYSSPACE, NULL, procp);
 	nd.ni_cnd.cn_cred = cred;
-	error = nfs_namei(&nd, fhp, len, slp, nam, &info.nmi_md,
-	    &info.nmi_dpos, &dirp, procp);
+	error = nfs_namei(&nd, fhp, len, slp, nam, &nfsd->nd_md,
+	    &nfsd->nd_dpos, &dirp, procp);
 	if (dirp) {
-		if (info.nmi_v3)
+		if (v3)
 			dirfor_ret = VOP_GETATTR(dirp, &dirfor, cred,
 				procp);
 		else {
@@ -2281,11 +2207,11 @@ nfsrv_rmdir(struct nfsrv_descript *nfsd,
 		}
 	}
 	if (error) {
-		if (nfsm_reply(&info, nfsd, slp, mrq, error,
-		    NFSX_WCCDATA(info.nmi_v3)) != 0)
+		if (nfsm_reply(nfsd, slp, mrq, &mb, error,
+		    NFSX_WCCDATA(v3)) != 0)
 			return 0;
 		nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
-		    &info);
+		    &mb);
 		if (dirp)
 			vrele(dirp);
 		return (0);
@@ -2329,12 +2255,11 @@ out:
 		diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp);
 		vrele(dirp);
 	}
-	if (nfsm_reply(&info, nfsd, slp, mrq, error,
-	    NFSX_WCCDATA(info.nmi_v3)) != 0)
+	if (nfsm_reply(nfsd, slp, mrq, &mb, error, NFSX_WCCDATA(v3)) != 0)
 		return 0;
-	if (info.nmi_v3) {
+	if (v3) {
 		nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
-		    &info);
+		    &mb);
 		error = 0;
 	}
 nfsmout:
@@ -2382,9 +2307,9 @@ nfsrv_readdir(struct nfsrv_descript *nfs
     struct proc *procp, struct mbuf **mrq)
 {
 	struct mbuf *nam = nfsd->nd_nam;
+	struct mbuf *mb;
 	struct ucred *cred = &nfsd->nd_cr;
 	struct dirent *dp;
-	struct nfsm_info	info;
 	u_int32_t *tl;
 	char *cpos, *cend, *rbuf;
 	struct vnode *vp;
@@ -2396,23 +2321,19 @@ nfsrv_readdir(struct nfsrv_descript *nfs
 	int len, nlen, pad, xfer, error = 0, getret = 1;
 	int siz, cnt, fullsiz, eofflag, rdonly;
 	u_quad_t off, toff, verf;
+	int v3;
 
-	info.nmi_mreq = NULL;
-	info.nmi_mrep = nfsd->nd_mrep;
-	info.nmi_md = nfsd->nd_md;
-	info.nmi_dpos = nfsd->nd_dpos;
-	info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
-	info.nmi_errorp = &error;
+	v3 = (nfsd->nd_flag & ND_NFSV3);
 
-	if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+	if (nfsm_srvmtofh1(nfsd, slp, mrq, &mb, &error) != 0)
 		return 0;
 	else if (error != 0)
 		goto nfsmout;
 	fhp = &nfh.fh_generic;
-	if (nfsm_srvmtofh2(&info, fhp) != 0)
+	if (nfsm_srvmtofh2(nfsd, fhp, &error) != 0)
 		goto nfsmout;
-	if (info.nmi_v3) {
-		tl = (uint32_t *)nfsm_dissect(&info, 5 * NFSX_UNSIGNED);
+	if (v3) {
+		tl = (uint32_t *)nfsd_dissect(nfsd, 5 * NFSX_UNSIGNED, &error);
 		if (tl == NULL)
 			goto nfsmout;
 		toff = fxdr_hyper(tl);
@@ -2420,7 +2341,7 @@ nfsrv_readdir(struct nfsrv_descript *nfs
 		verf = fxdr_hyper(tl);
 		tl += 2;
 	} else {
-		tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED);
+		tl = (uint32_t *)nfsd_dissect(nfsd, 2 * NFSX_UNSIGNED, &error);
 		if (tl == NULL)
 			goto nfsmout;
 		toff = fxdr_unsigned(u_quad_t, *tl++);
@@ -2428,7 +2349,7 @@ nfsrv_readdir(struct nfsrv_descript *nfs
 	off = toff;
 	cnt = fxdr_unsigned(int, *tl);
 	if (cnt == 0) {
-		if (info.nmi_v3)
+		if (v3)
 			error = NFSERR_TOOSMALL;
 		else
 			error = EBADRPC;
@@ -2447,23 +2368,23 @@ nfsrv_readdir(struct nfsrv_descript *nfs
 		}
 	}
 	if (error) {
-		if (nfsm_reply(&info, nfsd, slp, mrq, error,
+		if (nfsm_reply(nfsd, slp, mrq, &mb, error,
 		    NFSX_UNSIGNED) != 0)
 			return 0;
-		nfsm_srvpostop_attr(nfsd, getret, &at, &info);
+		nfsm_srvpostop_attr(nfsd, getret, &at, &mb);
 		error = 0;
 		goto nfsmout;
 	}
-	if (info.nmi_v3)
+	if (v3)
 		error = getret = VOP_GETATTR(vp, &at, cred, procp);
 	if (!error)
 		error = nfsrv_access(vp, VEXEC, cred, rdonly, procp, 0);
 	if (error) {
 		vput(vp);
-		if (nfsm_reply(&info, nfsd, slp, mrq, error,
-		    NFSX_POSTOPATTR(info.nmi_v3)) != 0)
+		if (nfsm_reply(nfsd, slp, mrq, &mb, error,
+		    NFSX_POSTOPATTR(v3)) != 0)
 			return 0;
-		nfsm_srvpostop_attr(nfsd, getret, &at, &info);
+		nfsm_srvpostop_attr(nfsd, getret, &at, &mb);
 		error = 0;
 		goto nfsmout;
 	}
@@ -2485,7 +2406,7 @@ again:
 	error = VOP_READDIR(vp, &io, cred, &eofflag);
 
 	off = (off_t)io.uio_offset;
-	if (info.nmi_v3) {
+	if (v3) {
 		getret = VOP_GETATTR(vp, &at, cred, procp);
 		if (!error)
 			error = getret;
@@ -2495,10 +2416,10 @@ again:
 	if (error) {
 		vrele(vp);
 		free(rbuf, M_TEMP, fullsiz);
-		if (nfsm_reply(&info, nfsd, slp, mrq, error,
-		    NFSX_POSTOPATTR(info.nmi_v3)) != 0)
+		if (nfsm_reply(nfsd, slp, mrq, &mb, error,
+		    NFSX_POSTOPATTR(v3)) != 0)
 			return 0;
-		nfsm_srvpostop_attr(nfsd, getret, &at, &info);
+		nfsm_srvpostop_attr(nfsd, getret, &at, &mb);
 		error = 0;
 		goto nfsmout;
 	}
@@ -2511,18 +2432,17 @@ again:
 		 */
 		if (siz == 0) {
 			vrele(vp);
-			if (nfsm_reply(&info, nfsd, slp, mrq, error,
-			    NFSX_POSTOPATTR(info.nmi_v3) +
-			    NFSX_COOKIEVERF(info.nmi_v3) +
+			if (nfsm_reply(nfsd, slp, mrq, &mb, error,
+			    NFSX_POSTOPATTR(v3) + NFSX_COOKIEVERF(v3) +
 			    2 * NFSX_UNSIGNED) != 0)
 				return 0;
-			if (info.nmi_v3) {
-				nfsm_srvpostop_attr(nfsd, getret, &at, &info);
-				tl = nfsm_build(&info.nmi_mb, 4 * NFSX_UNSIGNED);
+			if (v3) {
+				nfsm_srvpostop_attr(nfsd, getret, &at, &mb);
+				tl = nfsm_build(&mb, 4 * NFSX_UNSIGNED);
 				txdr_hyper(at.va_filerev, tl);
 				tl += 2;
 			} else
-				tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED);
+				tl = nfsm_build(&mb, 2 * NFSX_UNSIGNED);
 			*tl++ = nfs_false;
 			*tl = nfs_true;
 			free(rbuf, M_TEMP, fullsiz);
@@ -2550,13 +2470,12 @@ again:
 	}
 
 	len = 3 * NFSX_UNSIGNED;	/* paranoia, probably can be 0 */
-	if (nfsm_reply(&info, nfsd, slp, mrq, error,
-	    NFSX_POSTOPATTR(info.nmi_v3) +
-	    NFSX_COOKIEVERF(info.nmi_v3) + siz) != 0)
-		return 0;
-	if (info.nmi_v3) {
-		nfsm_srvpostop_attr(nfsd, getret, &at, &info);
-		tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED);
+	if (nfsm_reply(nfsd, slp, mrq, &mb, error,
+	    NFSX_POSTOPATTR(v3) + NFSX_COOKIEVERF(v3) + siz) != 0)
+		return 0;
+	if (v3) {
+		nfsm_srvpostop_attr(nfsd, getret, &at, &mb);
+		tl = nfsm_build(&mb, 2 * NFSX_UNSIGNED);
 		txdr_hyper(at.va_filerev, tl);
 	}
 
@@ -2566,7 +2485,7 @@ again:
 			nlen = dp->d_namlen;
 			pad = nfsm_padlen(nlen);
 			len += (4 * NFSX_UNSIGNED + nlen + pad);
-			if (info.nmi_v3)
+			if (v3)
 				len += 2 * NFSX_UNSIGNED;
 			if (len > cnt) {
 				eofflag = 0;
@@ -2576,23 +2495,22 @@ again:
 			 * Build the directory record xdr from
 			 * the dirent entry.
 			 */
-			tl = nfsm_build(&info.nmi_mb,
-			    (info.nmi_v3 ? 3 : 2) * NFSX_UNSIGNED);
+			tl = nfsm_build(&mb, (v3 ? 3 : 2) * NFSX_UNSIGNED);
 			*tl++ = nfs_true;
-			if (info.nmi_v3)
+			if (v3)
 				txdr_hyper(dp->d_fileno, tl);
 			else
 				*tl = txdr_unsigned((u_int32_t)dp->d_fileno);
 
 			/* And copy the name */
-			nfsm_strtombuf(&info.nmi_mb, dp->d_name, nlen);
+			nfsm_strtombuf(&mb, dp->d_name, nlen);
 
 			/* Finish off the record */
-			if (info.nmi_v3) {
-				tl = nfsm_build(&info.nmi_mb, 2*NFSX_UNSIGNED);
+			if (v3) {
+				tl = nfsm_build(&mb, 2*NFSX_UNSIGNED);
 				txdr_hyper(dp->d_off, tl);
 			} else {
-				tl = nfsm_build(&info.nmi_mb, NFSX_UNSIGNED);
+				tl = nfsm_build(&mb, NFSX_UNSIGNED);
 				*tl = txdr_unsigned((u_int32_t)dp->d_off);
 			}
 		}
@@ -2600,7 +2518,7 @@ again:
 		dp = (struct dirent *)cpos;
 	}
 	vrele(vp);
-	tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED);
+	tl = nfsm_build(&mb, 2 * NFSX_UNSIGNED);
 	*tl++ = nfs_false;
 	if (eofflag)
 		*tl = nfs_true;
@@ -2616,9 +2534,9 @@ nfsrv_readdirplus(struct nfsrv_descript 
     struct proc *procp, struct mbuf **mrq)
 {
 	struct mbuf *nam = nfsd->nd_nam;
+	struct mbuf *mb;
 	struct ucred *cred = &nfsd->nd_cr;
 	struct dirent *dp;
-	struct nfsm_info	info;
 	u_int32_t *tl;
 	char *cpos, *cend, *rbuf;
 	struct vnode *vp, *nvp;
@@ -2633,21 +2551,14 @@ nfsrv_readdirplus(struct nfsrv_descript 
 	int siz, cnt, fullsiz, eofflag, rdonly, dirlen;
 	u_quad_t off, toff, verf;
 
-	info.nmi_mreq = NULL;
-	info.nmi_mrep = nfsd->nd_mrep;
-	info.nmi_md = nfsd->nd_md;
-	info.nmi_dpos = nfsd->nd_dpos;
-	info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
-	info.nmi_errorp = &error;
-
-	if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+	if (nfsm_srvmtofh1(nfsd, slp, mrq, &mb, &error) != 0)
 		return 0;
 	else if (error != 0)
 		goto nfsmout;
 	fhp = &nfh.fh_generic;
-	if (nfsm_srvmtofh2(&info, fhp) != 0)
+	if (nfsm_srvmtofh2(nfsd, fhp, &error) != 0)
 		goto nfsmout;
-	tl = (uint32_t *)nfsm_dissect(&info, 6 * NFSX_UNSIGNED);
+	tl = (uint32_t *)nfsd_dissect(nfsd, 6 * NFSX_UNSIGNED, &error);
 	if (tl == NULL)
 		goto nfsmout;
 	off = toff = fxdr_hyper(tl);
@@ -2673,10 +2584,10 @@ nfsrv_readdirplus(struct nfsrv_descript 
 		}
 	}
 	if (error) {
-		if (nfsm_reply(&info, nfsd, slp, mrq, error,
+		if (nfsm_reply(nfsd, slp, mrq, &mb, error,
 		    NFSX_UNSIGNED) != 0)
 			return 0;
-		nfsm_srvpostop_attr(nfsd, getret, &at, &info);
+		nfsm_srvpostop_attr(nfsd, getret, &at, &mb);
 		error = 0;
 		goto nfsmout;
 	}
@@ -2685,10 +2596,10 @@ nfsrv_readdirplus(struct nfsrv_descript 
 		error = nfsrv_access(vp, VEXEC, cred, rdonly, procp, 0);
 	if (error) {
 		vput(vp);
-		if (nfsm_reply(&info, nfsd, slp, mrq, error,
+		if (nfsm_reply(nfsd, slp, mrq, &mb, error,
 		    NFSX_V3POSTOPATTR) != 0)
 			return 0;
-		nfsm_srvpostop_attr(nfsd, getret, &at, &info);
+		nfsm_srvpostop_attr(nfsd, getret, &at, &mb);
 		error = 0;
 		goto nfsmout;
 	}
@@ -2720,10 +2631,10 @@ again:
 	if (error) {
 		vrele(vp);
 		free(rbuf, M_TEMP, fullsiz);
-		if (nfsm_reply(&info, nfsd, slp, mrq, error,
+		if (nfsm_reply(nfsd, slp, mrq, &mb, error,
 		    NFSX_V3POSTOPATTR) != 0)
 			return 0;
-		nfsm_srvpostop_attr(nfsd, getret, &at, &info);
+		nfsm_srvpostop_attr(nfsd, getret, &at, &mb);
 		error = 0;
 		goto nfsmout;
 	}
@@ -2736,12 +2647,12 @@ again:
 		 */
 		if (siz == 0) {
 			vrele(vp);
-			if (nfsm_reply(&info, nfsd, slp, mrq, error,
+			if (nfsm_reply(nfsd, slp, mrq, &mb, error,
 			    NFSX_V3POSTOPATTR + NFSX_V3COOKIEVERF +
 			    2 * NFSX_UNSIGNED) != 0)
 				return 0;
-			nfsm_srvpostop_attr(nfsd, getret, &at, &info);
-			tl = nfsm_build(&info.nmi_mb, 4 * NFSX_UNSIGNED);
+			nfsm_srvpostop_attr(nfsd, getret, &at, &mb);
+			tl = nfsm_build(&mb, 4 * NFSX_UNSIGNED);
 			txdr_hyper(at.va_filerev, tl);
 			tl += 2;
 			*tl++ = nfs_false;
@@ -2783,10 +2694,10 @@ again:
 	 *  }
 	 */
 	dirlen = len = NFSX_V3POSTOPATTR + NFSX_V3COOKIEVERF + 2 * NFSX_UNSIGNED;
-	if (nfsm_reply(&info, nfsd, slp, mrq, error, cnt) != 0)
+	if (nfsm_reply(nfsd, slp, mrq, &mb, error, cnt) != 0)
 		return 0;
-	nfsm_srvpostop_attr(nfsd, getret, &at, &info);
-	tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED);
+	nfsm_srvpostop_attr(nfsd, getret, &at, &mb);
+	tl = nfsm_build(&mb, 2 * NFSX_UNSIGNED);
 	txdr_hyper(at.va_filerev, tl);
 
 	/* Loop through the records and build reply */
@@ -2839,12 +2750,12 @@ again:
 				break;
 			}
 
-			tl = nfsm_build(&info.nmi_mb, 3 * NFSX_UNSIGNED);
+			tl = nfsm_build(&mb, 3 * NFSX_UNSIGNED);
 			*tl++ = nfs_true;
 			txdr_hyper(dp->d_fileno, tl);
 
 			/* And copy the name */
-			nfsm_strtombuf(&info.nmi_mb, dp->d_name, nlen);
+			nfsm_strtombuf(&mb, dp->d_name, nlen);
 
 			/*
 			 * Build the directory record xdr from
@@ -2858,14 +2769,14 @@ again:
 			txdr_hyper(dp->d_off, fl.fl_off.nfsuquad);
 
 			/* Now copy the flrep structure out. */
-			nfsm_buftombuf(&info.nmi_mb, &fl, sizeof(struct flrep));
+			nfsm_buftombuf(&mb, &fl, sizeof(struct flrep));
 		}
 invalid:
 		cpos += dp->d_reclen;
 		dp = (struct dirent *)cpos;
 	}
 	vrele(vp);
-	tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED);
+	tl = nfsm_build(&mb, 2 * NFSX_UNSIGNED);
 	*tl++ = nfs_false;
 	if (eofflag)
 		*tl = nfs_true;
@@ -2884,10 +2795,10 @@ nfsrv_commit(struct nfsrv_descript *nfsd
     struct proc *procp, struct mbuf **mrq)
 {
 	struct mbuf *nam = nfsd->nd_nam;
+	struct mbuf *mb;
 	struct ucred *cred = &nfsd->nd_cr;
 	struct vattr bfor, aft;
 	struct vnode *vp;
-	struct nfsm_info	info;
 	struct timeval boottime;
 	nfsfh_t nfh;
 	fhandle_t *fhp;
@@ -2895,21 +2806,14 @@ nfsrv_commit(struct nfsrv_descript *nfsd
 	int error = 0, rdonly, for_ret = 1, aft_ret = 1, cnt;
 	u_quad_t off;
 
-	info.nmi_mreq = NULL;
-	info.nmi_mrep = nfsd->nd_mrep;
-	info.nmi_md = nfsd->nd_md;
-	info.nmi_dpos = nfsd->nd_dpos;
-	info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
-	info.nmi_errorp = &error;
-
-	if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+	if (nfsm_srvmtofh1(nfsd, slp, mrq, &mb, &error) != 0)
 		return 0;
 	else if (error != 0)
 		goto nfsmout;
 	fhp = &nfh.fh_generic;
-	if (nfsm_srvmtofh2(&info, fhp) != 0)
+	if (nfsm_srvmtofh2(nfsd, fhp, &error) != 0)
 		goto nfsmout;
-	tl = (uint32_t *)nfsm_dissect(&info, 3 * NFSX_UNSIGNED);
+	tl = (uint32_t *)nfsd_dissect(nfsd, 3 * NFSX_UNSIGNED, &error);
 	if (tl == NULL)
 		goto nfsmout;
 
@@ -2924,10 +2828,10 @@ nfsrv_commit(struct nfsrv_descript *nfsd
 		cnt = 0;
 	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
 	if (error) {
-		if (nfsm_reply(&info, nfsd, slp, mrq, error,
+		if (nfsm_reply(nfsd, slp, mrq, &mb, error,
 		    2 * NFSX_UNSIGNED) != 0)
 			return 0;
-		nfsm_srvwcc(nfsd, for_ret, &bfor, aft_ret, &aft, &info);
+		nfsm_srvwcc(nfsd, for_ret, &bfor, aft_ret, &aft, &mb);
 		error = 0;
 		goto nfsmout;
 	}
@@ -2935,12 +2839,12 @@ nfsrv_commit(struct nfsrv_descript *nfsd
 	error = VOP_FSYNC(vp, cred, MNT_WAIT, procp);
 	aft_ret = VOP_GETATTR(vp, &aft, cred, procp);
 	vput(vp);
-	if (nfsm_reply(&info, nfsd, slp, mrq, error,
+	if (nfsm_reply(nfsd, slp, mrq, &mb, error,
 	    NFSX_V3WCCDATA + NFSX_V3WRITEVERF) != 0)
 		return 0;
-	nfsm_srvwcc(nfsd, for_ret, &bfor, aft_ret, &aft, &info);
+	nfsm_srvwcc(nfsd, for_ret, &bfor, aft_ret, &aft, &mb);
 	if (!error) {
-		tl = nfsm_build(&info.nmi_mb, NFSX_V3WRITEVERF);
+		tl = nfsm_build(&mb, NFSX_V3WRITEVERF);
 		microboottime(&boottime);
 		*tl++ = txdr_unsigned(boottime.tv_sec);
 		*tl = txdr_unsigned(boottime.tv_usec);
@@ -2958,10 +2862,10 @@ nfsrv_statfs(struct nfsrv_descript *nfsd
     struct proc *procp, struct mbuf **mrq)
 {
 	struct mbuf *nam = nfsd->nd_nam;
+	struct mbuf *mb;
 	struct ucred *cred = &nfsd->nd_cr;
 	struct statfs *sf;
 	struct nfs_statfs *sfp;
-	struct nfsm_info	info;
 	int error = 0, rdonly, getret = 1;
 	struct vnode *vp;
 	struct vattr at;
@@ -2969,27 +2873,23 @@ nfsrv_statfs(struct nfsrv_descript *nfsd
 	fhandle_t *fhp;
 	struct statfs statfs;
 	u_quad_t tval;
+	int v3;
 
-	info.nmi_mreq = NULL;
-	info.nmi_mrep = nfsd->nd_mrep;
-	info.nmi_md = nfsd->nd_md;
-	info.nmi_dpos = nfsd->nd_dpos;
-	info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
-	info.nmi_errorp = &error;
+	v3 = (nfsd->nd_flag & ND_NFSV3);
 
-	if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+	if (nfsm_srvmtofh1(nfsd, slp, mrq, &mb, &error) != 0)
 		return 0;
 	else if (error != 0)
 		goto nfsmout;
 	fhp = &nfh.fh_generic;
-	if (nfsm_srvmtofh2(&info, fhp) != 0)
+	if (nfsm_srvmtofh2(nfsd, fhp, &error) != 0)
 		goto nfsmout;
 	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
 	if (error) {
-		if (nfsm_reply(&info, nfsd, slp, mrq, error,
+		if (nfsm_reply(nfsd, slp, mrq, &mb, error,
 		    NFSX_UNSIGNED) != 0)
 			return 0;
-		nfsm_srvpostop_attr(nfsd, getret, &at, &info);
+		nfsm_srvpostop_attr(nfsd, getret, &at, &mb);
 		error = 0;
 		goto nfsmout;
 	}
@@ -2997,17 +2897,17 @@ nfsrv_statfs(struct nfsrv_descript *nfsd
 	error = VFS_STATFS(vp->v_mount, sf, procp);
 	getret = VOP_GETATTR(vp, &at, cred, procp);
 	vput(vp);
-	if (nfsm_reply(&info, nfsd, slp, mrq, error,
-	    NFSX_POSTOPATTR(info.nmi_v3) + NFSX_STATFS(info.nmi_v3)) != 0)
+	if (nfsm_reply(nfsd, slp, mrq, &mb, error,
+	    NFSX_POSTOPATTR(v3) + NFSX_STATFS(v3)) != 0)
 		return 0;
-	if (info.nmi_v3)
-		nfsm_srvpostop_attr(nfsd, getret, &at, &info);
+	if (v3)
+		nfsm_srvpostop_attr(nfsd, getret, &at, &mb);
 	if (error) {
 		error = 0;
 		goto nfsmout;
 	}
-	sfp = nfsm_build(&info.nmi_mb, NFSX_STATFS(info.nmi_v3));
-	if (info.nmi_v3) {
+	sfp = nfsm_build(&mb, NFSX_STATFS(v3));
+	if (v3) {
 		tval = (u_quad_t)sf->f_blocks;
 		tval *= (u_quad_t)sf->f_bsize;
 		txdr_hyper(tval, &sfp->sf_tbytes);
@@ -3042,8 +2942,8 @@ nfsrv_fsinfo(struct nfsrv_descript *nfsd
     struct proc *procp, struct mbuf **mrq)
 {
 	struct mbuf *nam = nfsd->nd_nam;
+	struct mbuf *mb;
 	struct ucred *cred = &nfsd->nd_cr;
-	struct nfsm_info	info;
 	struct nfsv3_fsinfo *sip;
 	int error = 0, rdonly, getret = 1, pref;
 	struct vnode *vp;
@@ -3051,36 +2951,29 @@ nfsrv_fsinfo(struct nfsrv_descript *nfsd
 	nfsfh_t nfh;
 	fhandle_t *fhp;
 
-	info.nmi_mreq = NULL;
-	info.nmi_mrep = nfsd->nd_mrep;
-	info.nmi_md = nfsd->nd_md;
-	info.nmi_dpos = nfsd->nd_dpos;
-	info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
-	info.nmi_errorp = &error;
-
-	if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+	if (nfsm_srvmtofh1(nfsd, slp, mrq, &mb, &error) != 0)
 		return 0;
 	else if (error != 0)
 		goto nfsmout;
 	fhp = &nfh.fh_generic;
-	if (nfsm_srvmtofh2(&info, fhp) != 0)
+	if (nfsm_srvmtofh2(nfsd, fhp, &error) != 0)
 		goto nfsmout;
 	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
 	if (error) {
-		if (nfsm_reply(&info, nfsd, slp, mrq, error,
+		if (nfsm_reply(nfsd, slp, mrq, &mb, error,
 		    NFSX_UNSIGNED) != 0)
 			return 0;
-		nfsm_srvpostop_attr(nfsd, getret, &at, &info);
+		nfsm_srvpostop_attr(nfsd, getret, &at, &mb);
 		error = 0;
 		goto nfsmout;
 	}
 	getret = VOP_GETATTR(vp, &at, cred, procp);
 	vput(vp);
-	if (nfsm_reply(&info, nfsd, slp, mrq, error,
+	if (nfsm_reply(nfsd, slp, mrq, &mb, error,
 	    NFSX_V3POSTOPATTR + NFSX_V3FSINFO) != 0)
 		return 0;
-	nfsm_srvpostop_attr(nfsd, getret, &at, &info);
-	sip = nfsm_build(&info.nmi_mb, NFSX_V3FSINFO);
+	nfsm_srvpostop_attr(nfsd, getret, &at, &mb);
+	sip = nfsm_build(&mb, NFSX_V3FSINFO);
 
 	/*
 	 * XXX
@@ -3117,8 +3010,8 @@ nfsrv_pathconf(struct nfsrv_descript *nf
     struct proc *procp, struct mbuf **mrq)
 {
 	struct mbuf *nam = nfsd->nd_nam;
+	struct mbuf *mb;
 	struct ucred *cred = &nfsd->nd_cr;
-	struct nfsm_info	info;
 	struct nfsv3_pathconf *pc;
 	int error = 0, rdonly, getret = 1;
 	register_t linkmax, namemax, chownres, notrunc;
@@ -3127,26 +3020,19 @@ nfsrv_pathconf(struct nfsrv_descript *nf
 	nfsfh_t nfh;
 	fhandle_t *fhp;
 
-	info.nmi_mreq = NULL;
-	info.nmi_mrep = nfsd->nd_mrep;
-	info.nmi_md = nfsd->nd_md;
-	info.nmi_dpos = nfsd->nd_dpos;
-	info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
-	info.nmi_errorp = &error;
-
-	if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+	if (nfsm_srvmtofh1(nfsd, slp, mrq, &mb, &error) != 0)
 		return 0;
 	else if (error != 0)
 		goto nfsmout;
 	fhp = &nfh.fh_generic;
-	if (nfsm_srvmtofh2(&info, fhp) != 0)
+	if (nfsm_srvmtofh2(nfsd, fhp, &error) != 0)
 		goto nfsmout;
 	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
 	if (error) {
-		if (nfsm_reply(&info, nfsd, slp, mrq, error,
+		if (nfsm_reply(nfsd, slp, mrq, &mb, error,
 		    NFSX_UNSIGNED) != 0)
 			return 0;
-		nfsm_srvpostop_attr(nfsd, getret, &at, &info);
+		nfsm_srvpostop_attr(nfsd, getret, &at, &mb);
 		error = 0;
 		goto nfsmout;
 	}
@@ -3159,15 +3045,15 @@ nfsrv_pathconf(struct nfsrv_descript *nf
 		error = VOP_PATHCONF(vp, _PC_NO_TRUNC, &notrunc);
 	getret = VOP_GETATTR(vp, &at, cred, procp);
 	vput(vp);
-	if (nfsm_reply(&info, nfsd, slp, mrq, error,
+	if (nfsm_reply(nfsd, slp, mrq, &mb, error,
 	    NFSX_V3POSTOPATTR + NFSX_V3PATHCONF) != 0)
 		return 0;
-	nfsm_srvpostop_attr(nfsd, getret, &at, &info);
+	nfsm_srvpostop_attr(nfsd, getret, &at, &mb);
 	if (error) {
 		error = 0;
 		goto nfsmout;
 	}
-	pc = nfsm_build(&info.nmi_mb, NFSX_V3PATHCONF);
+	pc = nfsm_build(&mb, NFSX_V3PATHCONF);
 
 	pc->pc_linkmax = txdr_unsigned(linkmax);
 	pc->pc_namemax = txdr_unsigned(namemax);
@@ -3192,17 +3078,10 @@ int
 nfsrv_null(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
     struct proc *procp, struct mbuf **mrq)
 {
-	struct nfsm_info	info;
+	struct mbuf *mb;
 	int error = NFSERR_RETVOID;
 
-	info.nmi_mreq = NULL;
-	info.nmi_mrep = nfsd->nd_mrep;
-	info.nmi_md = nfsd->nd_md;
-	info.nmi_dpos = nfsd->nd_dpos;
-	info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
-	info.nmi_errorp = &error;
-
-	if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0)
+	if (nfsm_reply(nfsd, slp, mrq, &mb, error, 0) != 0)
 		return 0;
 	return (0);
 }
@@ -3214,21 +3093,14 @@ int
 nfsrv_noop(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
     struct proc *procp, struct mbuf **mrq)
 {
-	struct nfsm_info	info;
+	struct mbuf *mb;
 	int error;
 
-	info.nmi_mreq = NULL;
-	info.nmi_mrep = nfsd->nd_mrep;
-	info.nmi_md = nfsd->nd_md;
-	info.nmi_dpos = nfsd->nd_dpos;
-	info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
-	info.nmi_errorp = &error;
-
 	if (nfsd->nd_repstat)
 		error = nfsd->nd_repstat;
 	else
 		error = EPROCUNAVAIL;
-	if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0)
+	if (nfsm_reply(nfsd, slp, mrq, &mb, error, 0) != 0)
 		return 0;
 	return (0);
 }
Index: sys/nfs/nfs_socket.c
===================================================================
RCS file: /cvs/src/sys/nfs/nfs_socket.c,v
diff -u -p -r1.156 nfs_socket.c
--- sys/nfs/nfs_socket.c	16 Feb 2025 16:05:07 -0000	1.156
+++ sys/nfs/nfs_socket.c	9 Jul 2026 13:50:44 -0000
@@ -1450,23 +1450,18 @@ nfs_getreq(struct nfsrv_descript *nd, st
 	u_int32_t *tl;
 	u_int32_t nfsvers, auth_type;
 	int error = 0;
-	struct nfsm_info info;
 
-	info.nmi_mrep = nd->nd_mrep;
-	info.nmi_md = nd->nd_md;
-	info.nmi_dpos = nd->nd_dpos;
-	info.nmi_errorp = &error;
 	if (has_header) {
-		tl = (uint32_t *)nfsm_dissect(&info, 10 * NFSX_UNSIGNED);
+		tl = (uint32_t *)nfsd_dissect(nd, 10 * NFSX_UNSIGNED, &error);
 		if (tl == NULL)
 			goto nfsmout;
 		nd->nd_retxid = fxdr_unsigned(u_int32_t, *tl++);
 		if (*tl++ != rpc_call) {
-			m_freem(info.nmi_mrep);
+			m_freem(nd->nd_mrep);
 			return (EBADRPC);
 		}
 	} else {
-		tl = (uint32_t *)nfsm_dissect(&info, 8 * NFSX_UNSIGNED);
+		tl = (uint32_t *)nfsd_dissect(nd, 8 * NFSX_UNSIGNED, &error);
 		if (tl == NULL)
 			goto nfsmout;
 	}
@@ -1506,7 +1501,7 @@ nfs_getreq(struct nfsrv_descript *nd, st
 	auth_type = *tl++;
 	len = fxdr_unsigned(int, *tl++);
 	if (len < 0 || len > RPCAUTH_MAXSIZ) {
-		m_freem(info.nmi_mrep);
+		m_freem(nd->nd_mrep);
 		return (EBADRPC);
 	}
 
@@ -1514,12 +1509,12 @@ nfs_getreq(struct nfsrv_descript *nd, st
 	if (auth_type == rpc_auth_unix) {
 		len = fxdr_unsigned(int, *++tl);
 		if (len < 0 || len > NFS_MAXNAMLEN) {
-			m_freem(info.nmi_mrep);
+			m_freem(nd->nd_mrep);
 			return (EBADRPC);
 		}
-		if (nfsm_adv(&info, nfsm_rndup(len)) != 0)
+		if (nfsd_adv(nd, nfsm_rndup(len), &error) != 0)
 			goto nfsmout;
-		tl = (uint32_t *)nfsm_dissect(&info, 3 * NFSX_UNSIGNED);
+		tl = (uint32_t *)nfsd_dissect(nd, 3 * NFSX_UNSIGNED, &error);
 		if (tl == NULL)
 			goto nfsmout;
 		memset(&nd->nd_cr, 0, sizeof (struct ucred));
@@ -1528,11 +1523,11 @@ nfs_getreq(struct nfsrv_descript *nd, st
 		nd->nd_cr.cr_gid = fxdr_unsigned(gid_t, *tl++);
 		len = fxdr_unsigned(int, *tl);
 		if (len < 0 || len > RPCAUTH_UNIXGIDS) {
-			m_freem(info.nmi_mrep);
+			m_freem(nd->nd_mrep);
 			return (EBADRPC);
 		}
 		tl = (uint32_t *)
-		    nfsm_dissect(&info, (len + 2) * NFSX_UNSIGNED);
+		    nfsd_dissect(nd, (len + 2) * NFSX_UNSIGNED, &error);
 		if (tl == NULL)
 			goto nfsmout;
 		for (i = 0; i < len; i++) {
@@ -1545,11 +1540,11 @@ nfs_getreq(struct nfsrv_descript *nd, st
 		nd->nd_cr.cr_ngroups = (len > NGROUPS_MAX) ? NGROUPS_MAX : len;
 		len = fxdr_unsigned(int, *++tl);
 		if (len < 0 || len > RPCAUTH_MAXSIZ) {
-			m_freem(info.nmi_mrep);
+			m_freem(nd->nd_mrep);
 			return (EBADRPC);
 		}
 		if (len > 0) {
-			if (nfsm_adv(&info, nfsm_rndup(len)) != 0)
+			if (nfsd_adv(nd, nfsm_rndup(len), &error) != 0)
 				goto nfsmout;
 		}
 	} else {
@@ -1558,8 +1553,6 @@ nfs_getreq(struct nfsrv_descript *nd, st
 		return (0);
 	}
 
-	nd->nd_md = info.nmi_md;
-	nd->nd_dpos = info.nmi_dpos;
 	return (0);
 nfsmout:
 	return (error);
Index: sys/nfs/nfs_srvsubs.c
===================================================================
RCS file: /cvs/src/sys/nfs/nfs_srvsubs.c,v
diff -u -p -r1.2 nfs_srvsubs.c
--- sys/nfs/nfs_srvsubs.c	18 Sep 2024 05:21:19 -0000	1.2
+++ sys/nfs/nfs_srvsubs.c	9 Jul 2026 13:50:44 -0000
@@ -237,15 +237,15 @@ nfsm_adj(struct mbuf *mp, int len, int n
 void
 nfsm_srvwcc(struct nfsrv_descript *nfsd, int before_ret,
     struct vattr *before_vap, int after_ret, struct vattr *after_vap,
-    struct nfsm_info *info)
+    struct mbuf **mb)
 {
 	u_int32_t *tl;
 
 	if (before_ret) {
-		tl = nfsm_build(&info->nmi_mb, NFSX_UNSIGNED);
+		tl = nfsm_build(mb, NFSX_UNSIGNED);
 		*tl = nfs_false;
 	} else {
-		tl = nfsm_build(&info->nmi_mb, 7 * NFSX_UNSIGNED);
+		tl = nfsm_build(mb, 7 * NFSX_UNSIGNED);
 		*tl++ = nfs_true;
 		txdr_hyper(before_vap->va_size, tl);
 		tl += 2;
@@ -253,21 +253,21 @@ nfsm_srvwcc(struct nfsrv_descript *nfsd,
 		tl += 2;
 		txdr_nfsv3time(&(before_vap->va_ctime), tl);
 	}
-	nfsm_srvpostop_attr(nfsd, after_ret, after_vap, info);
+	nfsm_srvpostop_attr(nfsd, after_ret, after_vap, mb);
 }
 
 void
 nfsm_srvpostop_attr(struct nfsrv_descript *nfsd, int after_ret,
-    struct vattr *after_vap, struct nfsm_info *info)
+    struct vattr *after_vap, struct mbuf **mb)
 {
 	u_int32_t *tl;
 	struct nfs_fattr *fp;
 
 	if (after_ret) {
-		tl = nfsm_build(&info->nmi_mb, NFSX_UNSIGNED);
+		tl = nfsm_build(mb, NFSX_UNSIGNED);
 		*tl = nfs_false;
 	} else {
-		tl = nfsm_build(&info->nmi_mb, NFSX_UNSIGNED + NFSX_V3FATTR);
+		tl = nfsm_build(mb, NFSX_UNSIGNED + NFSX_V3FATTR);
 		*tl++ = nfs_true;
 		fp = (struct nfs_fattr *)tl;
 		nfsm_srvfattr(nfsd, after_vap, fp);
@@ -394,66 +394,59 @@ netaddr_match(int family, union nethosta
 }
 
 int
-nfsm_srvsattr(struct mbuf **mp, struct vattr *va, struct mbuf *mrep,
-    caddr_t *dposp)
+nfsm_srvsattr(struct nfsrv_descript *nfsd, struct vattr *va)
 {
-	struct nfsm_info	info;
 	int error = 0;
 	uint32_t *tl;
 
-	info.nmi_md = *mp;
-	info.nmi_dpos = *dposp;
-	info.nmi_mrep = mrep;
-	info.nmi_errorp = &error;
-
-	tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+	tl = (uint32_t *)nfsd_dissect(nfsd, NFSX_UNSIGNED, &error);
 	if (tl == NULL)
 		return error;
 	if (*tl == nfs_true) {
-		tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+		tl = (uint32_t *)nfsd_dissect(nfsd, NFSX_UNSIGNED, &error);
 		if (tl == NULL)
 			return error;
 		va->va_mode = nfstov_mode(*tl);
 	}
 
-	tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+	tl = (uint32_t *)nfsd_dissect(nfsd, NFSX_UNSIGNED, &error);
 	if (tl == NULL)
 		return error;
 	if (*tl == nfs_true) {
-		tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+		tl = (uint32_t *)nfsd_dissect(nfsd, NFSX_UNSIGNED, &error);
 		if (tl == NULL)
 			return error;
 		va->va_uid = fxdr_unsigned(uid_t, *tl);
 	}
 
-	tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+	tl = (uint32_t *)nfsd_dissect(nfsd, NFSX_UNSIGNED, &error);
 	if (tl == NULL)
 		return error;
 	if (*tl == nfs_true) {
-		tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+		tl = (uint32_t *)nfsd_dissect(nfsd, NFSX_UNSIGNED, &error);
 		if (tl == NULL)
 			return error;
 		va->va_gid = fxdr_unsigned(gid_t, *tl);
 	}
 
-	tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+	tl = (uint32_t *)nfsd_dissect(nfsd, NFSX_UNSIGNED, &error);
 	if (tl == NULL)
 		return error;
 	if (*tl == nfs_true) {
-		tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED);
+		tl = (uint32_t *)nfsd_dissect(nfsd, 2 * NFSX_UNSIGNED, &error);
 		if (tl == NULL)
 			return error;
 		va->va_size = fxdr_hyper(tl);
 	}
 
-	tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+	tl = (uint32_t *)nfsd_dissect(nfsd, NFSX_UNSIGNED, &error);
 	if (tl == NULL)
 		return error;
 	switch (fxdr_unsigned(int, *tl)) {
 	case NFSV3SATTRTIME_TOCLIENT:
 		va->va_vaflags |= VA_UTIMES_CHANGE;
 		va->va_vaflags &= ~VA_UTIMES_NULL;
-		tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED);
+		tl = (uint32_t *)nfsd_dissect(nfsd, 2 * NFSX_UNSIGNED, &error);
 		if (tl == NULL)
 			return error;
 		fxdr_nfsv3time(tl, &va->va_atime);
@@ -464,14 +457,14 @@ nfsm_srvsattr(struct mbuf **mp, struct v
 		break;
 	}
 
-	tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+	tl = (uint32_t *)nfsd_dissect(nfsd, NFSX_UNSIGNED, &error);
 	if (tl == NULL)
 		return error;
 	switch (fxdr_unsigned(int, *tl)) {
 	case NFSV3SATTRTIME_TOCLIENT:
 		va->va_vaflags |= VA_UTIMES_CHANGE;
 		va->va_vaflags &= ~VA_UTIMES_NULL;
-		tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED);
+		tl = (uint32_t *)nfsd_dissect(nfsd, 2 * NFSX_UNSIGNED, &error);
 		if (tl == NULL)
 			return error;
 		fxdr_nfsv3time(tl, &va->va_mtime);
@@ -482,7 +475,5 @@ nfsm_srvsattr(struct mbuf **mp, struct v
 		break;
 	}
 
-	*dposp = info.nmi_dpos;
-	*mp = info.nmi_md;
 	return 0;
 }
Index: sys/nfs/nfs_subs.c
===================================================================
RCS file: /cvs/src/sys/nfs/nfs_subs.c,v
diff -u -p -r1.151 nfs_subs.c
--- sys/nfs/nfs_subs.c	9 Sep 2024 03:50:14 -0000	1.151
+++ sys/nfs/nfs_subs.c	9 Jul 2026 13:50:44 -0000
@@ -1472,14 +1472,14 @@ nfsm_build(struct mbuf **mp, u_int len)
 }
 
 void
-nfsm_fhtom(struct nfsm_info *info, struct vnode *v, int v3)
+nfsm_fhtom(struct mbuf **mb, struct vnode *v, int v3)
 {
 	struct nfsnode *n = VTONFS(v);
 
 	if (v3) {
-		nfsm_strtombuf(&info->nmi_mb, n->n_fhp, n->n_fhsize);
+		nfsm_strtombuf(mb, n->n_fhp, n->n_fhsize);
 	} else {
-		nfsm_buftombuf(&info->nmi_mb, n->n_fhp, NFSX_V2FH);
+		nfsm_buftombuf(mb, n->n_fhp, NFSX_V2FH);
 	}
 }
 
Index: sys/nfs/nfs_var.h
===================================================================
RCS file: /cvs/src/sys/nfs/nfs_var.h,v
diff -u -p -r1.66 nfs_var.h
--- sys/nfs/nfs_var.h	9 Sep 2024 03:50:14 -0000	1.66
+++ sys/nfs/nfs_var.h	9 Jul 2026 13:50:44 -0000
@@ -148,15 +148,15 @@ int nfs_namei(struct nameidata *, fhandl
 		   struct proc *);
 void nfsm_adj(struct mbuf *, int, int);
 void nfsm_srvwcc(struct nfsrv_descript *, int, struct vattr *, int,
-		      struct vattr *, struct nfsm_info *);
+		      struct vattr *, struct mbuf **);
 void nfsm_srvpostop_attr(struct nfsrv_descript *, int, struct vattr *,
-			     struct nfsm_info *);
+			     struct mbuf **);
 void nfsm_srvfattr(struct nfsrv_descript *, struct vattr *,
 			struct nfs_fattr *);
 int nfsrv_fhtovp(fhandle_t *, int, struct vnode **, struct ucred *,
 		      struct nfssvc_sock *, struct mbuf *, int *);
 int netaddr_match(int, union nethostaddr *, struct mbuf *);
-int nfsm_srvsattr(struct mbuf **, struct vattr *, struct mbuf *, caddr_t *);
+int nfsm_srvsattr(struct nfsrv_descript *, struct vattr *);
 
 /* nfs_subs.c */
 struct mbuf *nfsm_reqhead(int);
@@ -183,7 +183,7 @@ void nfs_add_tobecommitted_range(struct 
 void nfs_del_tobecommitted_range(struct vnode *, struct buf *);
 void nfs_merge_commit_ranges(struct vnode *);
 int nfsrv_errmap(struct nfsrv_descript *, int);
-void nfsm_fhtom(struct nfsm_info *, struct vnode *, int);
+void nfsm_fhtom(struct mbuf **, struct vnode *, int);
 void nfsm_srvfhtom(struct mbuf **, fhandle_t *, int);
 
 /* nfs_syscalls.c */
Index: sys/nfs/nfs_vfsops.c
===================================================================
RCS file: /cvs/src/sys/nfs/nfs_vfsops.c,v
diff -u -p -r1.133 nfs_vfsops.c
--- sys/nfs/nfs_vfsops.c	12 Jun 2025 20:37:59 -0000	1.133
+++ sys/nfs/nfs_vfsops.c	9 Jul 2026 13:50:44 -0000
@@ -116,6 +116,7 @@ nfs_statfs(struct mount *mp, struct stat
 	struct vnode *vp;
 	struct nfs_statfs *sfp = NULL;
 	struct nfsm_info	info;
+	struct mbuf *mb;
 	struct nfsmount *nmp = VFSTONFS(mp);
 	int error = 0, retattr;
 	struct ucred *cred;
@@ -132,8 +133,8 @@ nfs_statfs(struct mount *mp, struct stat
 	if (info.nmi_v3 && (nmp->nm_flag & NFSMNT_GOTFSINFO) == 0)
 		(void)nfs_fsinfo(nmp, vp, cred, p);
 	nfsstats.rpccnt[NFSPROC_FSSTAT]++;
-	info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3));
-	nfsm_fhtom(&info, vp, info.nmi_v3);
+	mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3));
+	nfsm_fhtom(&mb, vp, info.nmi_v3);
 
 	info.nmi_procp = p;
 	info.nmi_cred = cred;
@@ -192,12 +193,13 @@ nfs_fsinfo(struct nfsmount *nmp, struct 
 {
 	struct nfsv3_fsinfo *fsp;
 	struct nfsm_info	info;
+	struct mbuf *mb;
 	u_int32_t pref, max;
 	int error = 0, retattr;
 
 	nfsstats.rpccnt[NFSPROC_FSINFO]++;
-	info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(1));
-	nfsm_fhtom(&info, vp, 1);
+	mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(1));
+	nfsm_fhtom(&mb, vp, 1);
 
 	info.nmi_procp = p;
 	info.nmi_cred = cred;
Index: sys/nfs/nfs_vnops.c
===================================================================
RCS file: /cvs/src/sys/nfs/nfs_vnops.c,v
diff -u -p -r1.209 nfs_vnops.c
--- sys/nfs/nfs_vnops.c	20 Sep 2025 13:53:36 -0000	1.209
+++ sys/nfs/nfs_vnops.c	9 Jul 2026 13:50:44 -0000
@@ -286,6 +286,7 @@ nfs_access(void *v)
 	int v3 = NFS_ISV3(vp);
 	int cachevalid;
 	struct nfsm_info	info;
+	struct mbuf *mb;
 
 	struct nfsnode *np = VTONFS(vp);
 
@@ -331,9 +332,9 @@ nfs_access(void *v)
 	 */
 	if (v3) {
 		nfsstats.rpccnt[NFSPROC_ACCESS]++;
-		info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(v3) + NFSX_UNSIGNED);
-		nfsm_fhtom(&info, vp, v3);
-		tl = nfsm_build(&info.nmi_mb, NFSX_UNSIGNED);
+		mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(v3) + NFSX_UNSIGNED);
+		nfsm_fhtom(&mb, vp, v3);
+		tl = nfsm_build(&mb, NFSX_UNSIGNED);
 		if (ap->a_mode & VREAD)
 			mode = NFSV3ACCESS_READ;
 		else
@@ -558,6 +559,7 @@ nfs_getattr(void *v)
 	struct vnode *vp = ap->a_vp;
 	struct nfsnode *np = VTONFS(vp);
 	struct nfsm_info	info;
+	struct mbuf *mb;
 	int error = 0;
 
 	info.nmi_v3 = NFS_ISV3(vp);
@@ -574,8 +576,8 @@ nfs_getattr(void *v)
 		return (0);
 
 	nfsstats.rpccnt[NFSPROC_GETATTR]++;
-	info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3));
-	nfsm_fhtom(&info, vp, info.nmi_v3);
+	mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3));
+	nfsm_fhtom(&mb, vp, info.nmi_v3);
 	info.nmi_procp = ap->a_p;
 	info.nmi_cred = ap->a_cred;
 	info.nmi_errorp = &error;
@@ -719,6 +721,7 @@ nfs_setattrrpc(struct vnode *vp, struct 
 {
 	struct nfsv2_sattr *sp;
 	struct nfsm_info	info;
+	struct mbuf *mb;
 	u_int32_t *tl;
 	int error = 0, wccflag = NFSV3_WCCRATTR;
 	int v3 = NFS_ISV3(vp);
@@ -726,16 +729,16 @@ nfs_setattrrpc(struct vnode *vp, struct 
 	info.nmi_v3 = NFS_ISV3(vp);
 
 	nfsstats.rpccnt[NFSPROC_SETATTR]++;
-	info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(v3) + NFSX_SATTR(v3));
-	nfsm_fhtom(&info, vp, v3);
+	mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(v3) + NFSX_SATTR(v3));
+	nfsm_fhtom(&mb, vp, v3);
 	info.nmi_errorp = &error;
 
 	if (info.nmi_v3) {
-		nfsm_v3attrbuild(&info.nmi_mb, vap, 1);
-		tl = nfsm_build(&info.nmi_mb, NFSX_UNSIGNED);
+		nfsm_v3attrbuild(&mb, vap, 1);
+		tl = nfsm_build(&mb, NFSX_UNSIGNED);
 		*tl = nfs_false;
 	} else {
-		sp = nfsm_build(&info.nmi_mb, NFSX_V2SATTR);
+		sp = nfsm_build(&mb, NFSX_V2SATTR);
 		if (vap->va_mode == (mode_t)VNOVAL)
 			sp->sa_mode = nfs_xdrneg1;
 		else
@@ -805,6 +808,7 @@ nfs_lookup(void *v)
 	struct vnode *dvp = ap->a_dvp;
 	struct vnode **vpp = ap->a_vpp;
 	struct nfsm_info	info;
+	struct mbuf *mb;
 	int flags;
 	struct vnode *newvp;
 	struct nfsmount *nmp;
@@ -907,10 +911,10 @@ dorpc:
 	nfsstats.lookupcache_misses++;
 	nfsstats.rpccnt[NFSPROC_LOOKUP]++;
 	len = cnp->cn_namelen;
-	info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3) +
+	mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3) +
 	    NFSX_UNSIGNED + nfsm_rndup(len));
-	nfsm_fhtom(&info, dvp, info.nmi_v3);
-	if (nfsm_strtom(&info, cnp->cn_nameptr, len, NFS_MAXNAMLEN) != 0)
+	nfsm_fhtom(&mb, dvp, info.nmi_v3);
+	if (nfsm_strtom(&info, &mb, cnp->cn_nameptr, len, NFS_MAXNAMLEN) != 0)
 		goto nfsmout;
 
 	info.nmi_procp = cnp->cn_proc;
@@ -1147,14 +1151,15 @@ int
 nfs_readlinkrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred)
 {
 	struct nfsm_info	info;
+	struct mbuf *mb;
 	int error = 0, len, attrflag;
 
 	info.nmi_v3 = NFS_ISV3(vp);
 	info.nmi_errorp = &error;
 
 	nfsstats.rpccnt[NFSPROC_READLINK]++;
-	info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3));
-	nfsm_fhtom(&info, vp, info.nmi_v3);
+	mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3));
+	nfsm_fhtom(&mb, vp, info.nmi_v3);
 
 	info.nmi_procp = curproc;
 	info.nmi_cred = cred;
@@ -1185,6 +1190,7 @@ int
 nfs_readrpc(struct vnode *vp, struct uio *uiop)
 {
 	struct nfsm_info	info;
+	struct mbuf *mb;
 	u_int32_t *tl;
 	struct nfsmount *nmp;
 	int error = 0, len, retlen, tsiz, eof, attrflag;
@@ -1201,10 +1207,10 @@ nfs_readrpc(struct vnode *vp, struct uio
 	while (tsiz > 0) {
 		nfsstats.rpccnt[NFSPROC_READ]++;
 		len = (tsiz > nmp->nm_rsize) ? nmp->nm_rsize : tsiz;
-		info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3) +
+		mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3) +
 		    NFSX_UNSIGNED * 3);
-		nfsm_fhtom(&info, vp, info.nmi_v3);
-		tl = nfsm_build(&info.nmi_mb, NFSX_UNSIGNED * 3);
+		nfsm_fhtom(&mb, vp, info.nmi_v3);
+		tl = nfsm_build(&mb, NFSX_UNSIGNED * 3);
 		if (info.nmi_v3) {
 			txdr_hyper(uiop->uio_offset, tl);
 			*(tl + 2) = txdr_unsigned(len);
@@ -1260,6 +1266,7 @@ int
 nfs_writerpc(struct vnode *vp, struct uio *uiop, int *iomode, int *must_commit)
 {
 	struct nfsm_info	info;
+	struct mbuf *mb;
 	u_int32_t *tl;
 	int32_t backup;
 	struct nfsmount *nmp = VFSTONFS(vp->v_mount);
@@ -1268,6 +1275,7 @@ nfs_writerpc(struct vnode *vp, struct ui
 
 	info.nmi_v3 = NFS_ISV3(vp);
 	info.nmi_errorp = &error;
+	info.nmi_mrep = NULL;
 
 #ifdef DIAGNOSTIC
 	if (uiop->uio_iovcnt != 1)
@@ -1280,11 +1288,11 @@ nfs_writerpc(struct vnode *vp, struct ui
 	while (tsiz > 0) {
 		nfsstats.rpccnt[NFSPROC_WRITE]++;
 		len = (tsiz > nmp->nm_wsize) ? nmp->nm_wsize : tsiz;
-		info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3)
+		mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3)
 		    + 5 * NFSX_UNSIGNED + nfsm_rndup(len));
-		nfsm_fhtom(&info, vp, info.nmi_v3);
+		nfsm_fhtom(&mb, vp, info.nmi_v3);
 		if (info.nmi_v3) {
-			tl = nfsm_build(&info.nmi_mb, 5 * NFSX_UNSIGNED);
+			tl = nfsm_build(&mb, 5 * NFSX_UNSIGNED);
 			txdr_hyper(uiop->uio_offset, tl);
 			tl += 2;
 			*tl++ = txdr_unsigned(len);
@@ -1293,7 +1301,7 @@ nfs_writerpc(struct vnode *vp, struct ui
 		} else {
 			u_int32_t x;
 
-			tl = nfsm_build(&info.nmi_mb, 4 * NFSX_UNSIGNED);
+			tl = nfsm_build(&mb, 4 * NFSX_UNSIGNED);
 			/* Set both "begin" and "current" to non-garbage. */
 			x = txdr_unsigned((u_int32_t)uiop->uio_offset);
 			*tl++ = x;	/* "begin offset" */
@@ -1303,7 +1311,7 @@ nfs_writerpc(struct vnode *vp, struct ui
 			*tl = x;	/* size of this write */
 
 		}
-		nfsm_uiotombuf(&info.nmi_mb, uiop, len);
+		nfsm_uiotombuf(&mb, uiop, len);
 
 		info.nmi_procp = curproc;
 		info.nmi_cred = VTONFS(vp)->n_wcred;
@@ -1315,7 +1323,6 @@ nfs_writerpc(struct vnode *vp, struct ui
 		}
 
 		if (error) {
-			m_freem(info.nmi_mrep);
 			goto nfsmout;
 		}
 
@@ -1328,6 +1335,7 @@ nfs_writerpc(struct vnode *vp, struct ui
 			rlen = fxdr_unsigned(int, *tl++);
 			if (rlen <= 0) {
 				error = NFSERR_IO;
+				/* info.nmi_mrep free'd after the loop */
 				break;
 			} else if (rlen < len) {
 				backup = len - rlen;
@@ -1367,9 +1375,11 @@ nfs_writerpc(struct vnode *vp, struct ui
 		if (wccflag)
 		    VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr.va_mtime;
 		m_freem(info.nmi_mrep);
+		info.nmi_mrep = NULL;
 		tsiz -= len;
 	}
 nfsmout:
+	m_freem(info.nmi_mrep);
 	*iomode = committed;
 	if (error)
 		uiop->uio_resid = tsiz;
@@ -1438,6 +1448,7 @@ nfs_mknodrpc(struct vnode *dvp, struct v
 {
 	struct nfsv2_sattr *sp;
 	struct nfsm_info	info;
+	struct mbuf *mb;
 	u_int32_t *tl;
 	struct vnode *newvp = NULL;
 	struct nfsnode *np = NULL;
@@ -1456,25 +1467,25 @@ nfs_mknodrpc(struct vnode *dvp, struct v
 		return (EOPNOTSUPP);
 	}
 	nfsstats.rpccnt[NFSPROC_MKNOD]++;
-	info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3) +
+	mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3) +
 	    4 * NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen) +
 	    NFSX_SATTR(info.nmi_v3));
-	nfsm_fhtom(&info, dvp, info.nmi_v3);
-	if (nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen,
+	nfsm_fhtom(&mb, dvp, info.nmi_v3);
+	if (nfsm_strtom(&info, &mb, cnp->cn_nameptr, cnp->cn_namelen,
 	    NFS_MAXNAMLEN) != 0)
 		goto nfsmout;
 
 	if (info.nmi_v3) {
-		tl = nfsm_build(&info.nmi_mb, NFSX_UNSIGNED);
+		tl = nfsm_build(&mb, NFSX_UNSIGNED);
 		*tl++ = vtonfsv3_type(vap->va_type);
-		nfsm_v3attrbuild(&info.nmi_mb, vap, 0);
+		nfsm_v3attrbuild(&mb, vap, 0);
 		if (vap->va_type == VCHR || vap->va_type == VBLK) {
-			tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED);
+			tl = nfsm_build(&mb, 2 * NFSX_UNSIGNED);
 			*tl++ = txdr_unsigned(major(vap->va_rdev));
 			*tl = txdr_unsigned(minor(vap->va_rdev));
 		}
 	} else {
-		sp = nfsm_build(&info.nmi_mb, NFSX_V2SATTR);
+		sp = nfsm_build(&mb, NFSX_V2SATTR);
 		sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode);
 		sp->sa_uid = nfs_xdrneg1;
 		sp->sa_gid = nfs_xdrneg1;
@@ -1548,6 +1559,7 @@ nfs_create(void *v)
 	struct componentname *cnp = ap->a_cnp;
 	struct nfsv2_sattr *sp;
 	struct nfsm_info	info;
+	struct mbuf *mb;
 	struct timespec ts;
 	u_int32_t *tl;
 	struct nfsnode *np = NULL;
@@ -1568,25 +1580,25 @@ nfs_create(void *v)
 
 again:
 	nfsstats.rpccnt[NFSPROC_CREATE]++;
-	info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3) +
+	mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3) +
 	    2 * NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen) +
 	    NFSX_SATTR(info.nmi_v3));
-	nfsm_fhtom(&info, dvp, info.nmi_v3);
-	if (nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen,
+	nfsm_fhtom(&mb, dvp, info.nmi_v3);
+	if (nfsm_strtom(&info, &mb, cnp->cn_nameptr, cnp->cn_namelen,
 	    NFS_MAXNAMLEN) != 0)
 		goto nfsmout;
 	if (info.nmi_v3) {
-		tl = nfsm_build(&info.nmi_mb, NFSX_UNSIGNED);
+		tl = nfsm_build(&mb, NFSX_UNSIGNED);
 		if (fmode & O_EXCL) {
 			*tl = txdr_unsigned(NFSV3CREATE_EXCLUSIVE);
-			tl = nfsm_build(&info.nmi_mb, NFSX_V3CREATEVERF);
+			tl = nfsm_build(&mb, NFSX_V3CREATEVERF);
 			arc4random_buf(tl, sizeof(*tl) * 2);
 		} else {
 			*tl = txdr_unsigned(NFSV3CREATE_UNCHECKED);
-			nfsm_v3attrbuild(&info.nmi_mb, vap, 0);
+			nfsm_v3attrbuild(&mb, vap, 0);
 		}
 	} else {
-		sp = nfsm_build(&info.nmi_mb, NFSX_V2SATTR);
+		sp = nfsm_build(&mb, NFSX_V2SATTR);
 		sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode);
 		sp->sa_uid = nfs_xdrneg1;
 		sp->sa_gid = nfs_xdrneg1;
@@ -1741,16 +1753,17 @@ nfs_removerpc(struct vnode *dvp, char *n
     struct proc *proc)
 {
 	struct nfsm_info	info;
+	struct mbuf *mb;
 	int error = 0, wccflag = NFSV3_WCCRATTR;
 
 	info.nmi_v3 = NFS_ISV3(dvp);
 	info.nmi_errorp = &error;
 
 	nfsstats.rpccnt[NFSPROC_REMOVE]++;
-	info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3) +
+	mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3) +
 	     NFSX_UNSIGNED + nfsm_rndup(namelen));
-	nfsm_fhtom(&info, dvp, info.nmi_v3);
-	if (nfsm_strtom(&info, name, namelen, NFS_MAXNAMLEN) != 0)
+	nfsm_fhtom(&mb, dvp, info.nmi_v3);
+	if (nfsm_strtom(&info, &mb, name, namelen, NFS_MAXNAMLEN) != 0)
 		goto nfsmout;
 
 	info.nmi_procp = proc;
@@ -1856,19 +1869,20 @@ nfs_renamerpc(struct vnode *fdvp, char *
     struct proc *proc)
 {
 	struct nfsm_info	info;
+	struct mbuf *mb;
 	int error = 0, fwccflag = NFSV3_WCCRATTR, twccflag = NFSV3_WCCRATTR;
 
 	info.nmi_v3 = NFS_ISV3(fdvp);
 	info.nmi_errorp = &error;
 
 	nfsstats.rpccnt[NFSPROC_RENAME]++;
-	info.nmi_mb = info.nmi_mreq = nfsm_reqhead((NFSX_FH(info.nmi_v3) +
+	mb = info.nmi_mreq = nfsm_reqhead((NFSX_FH(info.nmi_v3) +
 	    NFSX_UNSIGNED) * 2 + nfsm_rndup(fnamelen) + nfsm_rndup(tnamelen));
-	nfsm_fhtom(&info, fdvp, info.nmi_v3);
-	if (nfsm_strtom(&info, fnameptr, fnamelen, NFS_MAXNAMLEN) != 0)
+	nfsm_fhtom(&mb, fdvp, info.nmi_v3);
+	if (nfsm_strtom(&info, &mb, fnameptr, fnamelen, NFS_MAXNAMLEN) != 0)
 		goto nfsmout;
-	nfsm_fhtom(&info, tdvp, info.nmi_v3);
-	if (nfsm_strtom(&info, tnameptr, tnamelen, NFS_MAXNAMLEN) != 0)
+	nfsm_fhtom(&mb, tdvp, info.nmi_v3);
+	if (nfsm_strtom(&info, &mb, tnameptr, tnamelen, NFS_MAXNAMLEN) != 0)
 		goto nfsmout;
 
 	info.nmi_procp = proc;
@@ -1903,6 +1917,7 @@ nfs_link(void *v)
 	struct vnode *dvp = ap->a_dvp;
 	struct componentname *cnp = ap->a_cnp;
 	struct nfsm_info	info;
+	struct mbuf *mb;
 	int error = 0, wccflag = NFSV3_WCCRATTR, attrflag = 0;
 
 	info.nmi_v3 = NFS_ISV3(vp);
@@ -1923,11 +1938,11 @@ nfs_link(void *v)
 	VOP_FSYNC(vp, cnp->cn_cred, MNT_WAIT, cnp->cn_proc);
 
 	nfsstats.rpccnt[NFSPROC_LINK]++;
-	info.nmi_mb = info.nmi_mreq = nfsm_reqhead(2 * NFSX_FH(info.nmi_v3) +
+	mb = info.nmi_mreq = nfsm_reqhead(2 * NFSX_FH(info.nmi_v3) +
 	    NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen));
-	nfsm_fhtom(&info, vp, info.nmi_v3);
-	nfsm_fhtom(&info, dvp, info.nmi_v3);
-	if (nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen,
+	nfsm_fhtom(&mb, vp, info.nmi_v3);
+	nfsm_fhtom(&mb, dvp, info.nmi_v3);
+	if (nfsm_strtom(&info, &mb, cnp->cn_nameptr, cnp->cn_namelen,
 	    NFS_MAXNAMLEN) != 0)
 		goto nfsmout;
 
@@ -1968,6 +1983,7 @@ nfs_symlink(void *v)
 	struct componentname *cnp = ap->a_cnp;
 	struct nfsv2_sattr *sp;
 	struct nfsm_info	info;
+	struct mbuf *mb;
 	int slen, error = 0, wccflag = NFSV3_WCCRATTR, gotvp;
 	struct vnode *newvp = NULL;
 
@@ -1976,19 +1992,19 @@ nfs_symlink(void *v)
 
 	nfsstats.rpccnt[NFSPROC_SYMLINK]++;
 	slen = strlen(ap->a_target);
-	info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3) +
+	mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3) +
 	    2 * NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen) + nfsm_rndup(slen) +
 	    NFSX_SATTR(info.nmi_v3));
-	nfsm_fhtom(&info, dvp, info.nmi_v3);
-	if (nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen,
+	nfsm_fhtom(&mb, dvp, info.nmi_v3);
+	if (nfsm_strtom(&info, &mb, cnp->cn_nameptr, cnp->cn_namelen,
 	    NFS_MAXNAMLEN) != 0)
 		goto nfsmout;
 	if (info.nmi_v3)
-		nfsm_v3attrbuild(&info.nmi_mb, vap, 0);
-	if (nfsm_strtom(&info, ap->a_target, slen, NFS_MAXPATHLEN) != 0)
+		nfsm_v3attrbuild(&mb, vap, 0);
+	if (nfsm_strtom(&info, &mb, ap->a_target, slen, NFS_MAXPATHLEN) != 0)
 		goto nfsmout;
 	if (!info.nmi_v3) {
-		sp = nfsm_build(&info.nmi_mb, NFSX_V2SATTR);
+		sp = nfsm_build(&mb, NFSX_V2SATTR);
 		sp->sa_mode = vtonfsv2_mode(VLNK, vap->va_mode);
 		sp->sa_uid = nfs_xdrneg1;
 		sp->sa_gid = nfs_xdrneg1;
@@ -2034,6 +2050,7 @@ nfs_mkdir(void *v)
 	struct componentname *cnp = ap->a_cnp;
 	struct nfsv2_sattr *sp;
 	struct nfsm_info	info;
+	struct mbuf *mb;
 	int len;
 	struct nfsnode *np = NULL;
 	struct vnode *newvp = NULL;
@@ -2045,16 +2062,16 @@ nfs_mkdir(void *v)
 
 	len = cnp->cn_namelen;
 	nfsstats.rpccnt[NFSPROC_MKDIR]++;
-	info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3) +
+	mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3) +
 	    NFSX_UNSIGNED + nfsm_rndup(len) + NFSX_SATTR(info.nmi_v3));
-	nfsm_fhtom(&info, dvp, info.nmi_v3);
-	if (nfsm_strtom(&info, cnp->cn_nameptr, len, NFS_MAXNAMLEN) != 0)
+	nfsm_fhtom(&mb, dvp, info.nmi_v3);
+	if (nfsm_strtom(&info, &mb, cnp->cn_nameptr, len, NFS_MAXNAMLEN) != 0)
 		goto nfsmout;
 
 	if (info.nmi_v3) {
-		nfsm_v3attrbuild(&info.nmi_mb, vap, 0);
+		nfsm_v3attrbuild(&mb, vap, 0);
 	} else {
-		sp = nfsm_build(&info.nmi_mb, NFSX_V2SATTR);
+		sp = nfsm_build(&mb, NFSX_V2SATTR);
 		sp->sa_mode = vtonfsv2_mode(VDIR, vap->va_mode);
 		sp->sa_uid = nfs_xdrneg1;
 		sp->sa_gid = nfs_xdrneg1;
@@ -2115,16 +2132,17 @@ nfs_rmdir(void *v)
 	struct vnode *dvp = ap->a_dvp;
 	struct componentname *cnp = ap->a_cnp;
 	struct nfsm_info	info;
+	struct mbuf *mb;
 	int error = 0, wccflag = NFSV3_WCCRATTR;
 
 	info.nmi_v3 = NFS_ISV3(dvp);
 	info.nmi_errorp = &error;
 
 	nfsstats.rpccnt[NFSPROC_RMDIR]++;
-	info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3) +
+	mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3) +
 	    NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen));
-	nfsm_fhtom(&info, dvp, info.nmi_v3);
-	if (nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen,
+	nfsm_fhtom(&mb, dvp, info.nmi_v3);
+	if (nfsm_strtom(&info, &mb, cnp->cn_nameptr, cnp->cn_namelen,
 	    NFS_MAXNAMLEN) != 0)
 		goto nfsmout;
 
@@ -2314,6 +2332,7 @@ nfs_readdirrpc(struct vnode *vp, struct 
 	struct nfs_dirent *ndp = NULL;
 	struct dirent *dp = NULL;
 	struct nfsm_info	info;
+	struct mbuf *mb;
 	u_int32_t *tl;
 	caddr_t cp;
 	nfsuint64 cookie;
@@ -2341,11 +2360,11 @@ nfs_readdirrpc(struct vnode *vp, struct 
 	 */
 	while (more_dirs && bigenough) {
 		nfsstats.rpccnt[NFSPROC_READDIR]++;
-		info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3)
+		mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3)
 		    + NFSX_READDIR(info.nmi_v3));
-		nfsm_fhtom(&info, vp, info.nmi_v3);
+		nfsm_fhtom(&mb, vp, info.nmi_v3);
 		if (info.nmi_v3) {
-			tl = nfsm_build(&info.nmi_mb, 5 * NFSX_UNSIGNED);
+			tl = nfsm_build(&mb, 5 * NFSX_UNSIGNED);
 			*tl++ = cookie.nfsuquad[0];
 			*tl++ = cookie.nfsuquad[1];
 			if (cookie.nfsuquad[0] == 0 &&
@@ -2357,7 +2376,7 @@ nfs_readdirrpc(struct vnode *vp, struct 
 				*tl++ = dnp->n_cookieverf.nfsuquad[1];
 			}
 		} else {
-			tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED);
+			tl = nfsm_build(&mb, 2 * NFSX_UNSIGNED);
 			*tl++ = cookie.nfsuquad[1];
 		}
 		*tl = txdr_unsigned(nmp->nm_readdirsize);
@@ -2523,6 +2542,7 @@ nfs_readdirplusrpc(struct vnode *vp, str
 	struct nfs_dirent *ndirp = NULL;
 	struct dirent *dp = NULL;
 	struct nfsm_info	info;
+	struct mbuf *mb;
 	u_int32_t *tl;
 	caddr_t cp;
 	struct vnode *newvp;
@@ -2556,9 +2576,9 @@ nfs_readdirplusrpc(struct vnode *vp, str
 	 */
 	while (more_dirs && bigenough) {
 		nfsstats.rpccnt[NFSPROC_READDIRPLUS]++;
-		info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(1) + 6 * NFSX_UNSIGNED);
-		nfsm_fhtom(&info, vp, 1);
-		tl = nfsm_build(&info.nmi_mb, 6 * NFSX_UNSIGNED);
+		mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(1) + 6 * NFSX_UNSIGNED);
+		nfsm_fhtom(&mb, vp, 1);
+		tl = nfsm_build(&mb, 6 * NFSX_UNSIGNED);
 		*tl++ = cookie.nfsuquad[0];
 		*tl++ = cookie.nfsuquad[1];
 		if (cookie.nfsuquad[0] == 0 &&
@@ -2850,6 +2870,7 @@ nfs_lookitup(struct vnode *dvp, char *na
     struct proc *procp, struct nfsnode **npp)
 {
 	struct nfsm_info	info;
+	struct mbuf *mb;
 	struct vnode *newvp = NULL;
 	struct nfsnode *np = NULL, *dnp = VTONFS(dvp);
 	int error = 0, fhlen, attrflag = 0;
@@ -2859,10 +2880,10 @@ nfs_lookitup(struct vnode *dvp, char *na
 	info.nmi_errorp = &error;
 
 	nfsstats.rpccnt[NFSPROC_LOOKUP]++;
-	info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3) + NFSX_UNSIGNED +
+	mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3) + NFSX_UNSIGNED +
 	    nfsm_rndup(len));
-	nfsm_fhtom(&info, dvp, info.nmi_v3);
-	if (nfsm_strtom(&info, name, len, NFS_MAXNAMLEN) != 0)
+	nfsm_fhtom(&mb, dvp, info.nmi_v3);
+	if (nfsm_strtom(&info, &mb, name, len, NFS_MAXNAMLEN) != 0)
 		goto nfsmout;
 
 	info.nmi_procp = procp;
@@ -2931,6 +2952,7 @@ int
 nfs_commit(struct vnode *vp, u_quad_t offset, int cnt, struct proc *procp)
 {
 	struct nfsm_info	info;
+	struct mbuf *mb;
 	u_int32_t *tl;
 	struct nfsmount *nmp = VFSTONFS(vp->v_mount);
 	int error = 0, wccflag = NFSV3_WCCRATTR;
@@ -2938,11 +2960,11 @@ nfs_commit(struct vnode *vp, u_quad_t of
 	if ((nmp->nm_flag & NFSMNT_HASWRITEVERF) == 0)
 		return (0);
 	nfsstats.rpccnt[NFSPROC_COMMIT]++;
-	info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(1));
-	nfsm_fhtom(&info, vp, 1);
+	mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(1));
+	nfsm_fhtom(&mb, vp, 1);
 	info.nmi_errorp = &error;
 
-	tl = nfsm_build(&info.nmi_mb, 3 * NFSX_UNSIGNED);
+	tl = nfsm_build(&mb, 3 * NFSX_UNSIGNED);
 	txdr_hyper(offset, tl);
 	tl += 2;
 	*tl = txdr_unsigned(cnt);
Index: sys/nfs/nfsm_subs.h
===================================================================
RCS file: /cvs/src/sys/nfs/nfsm_subs.h,v
diff -u -p -r1.49 nfsm_subs.h
--- sys/nfs/nfsm_subs.h	11 Sep 2024 12:22:34 -0000	1.49
+++ sys/nfs/nfsm_subs.h	9 Jul 2026 13:50:44 -0000
@@ -48,7 +48,6 @@ struct nfsm_info {
 
 	/* Setting up / Tearing down. */
 	struct mbuf	*nmi_md;
-	struct mbuf	*nmi_mb;
 	caddr_t		 nmi_dpos;
 
 	int		 nmi_v3;  
@@ -57,6 +56,30 @@ struct nfsm_info {
 };
 
 static inline void *
+nfsd_dissect(struct nfsrv_descript *nfsd, int s, int *errorp)
+{
+	caddr_t ret;
+	int avail, error;
+
+	avail = mtod(nfsd->nd_md, caddr_t) + nfsd->nd_md->m_len -
+	    nfsd->nd_dpos;
+	if (avail >= s) {
+		ret = nfsd->nd_dpos;
+		nfsd->nd_dpos += s;
+		return ret;
+	}
+	error = nfsm_disct(&nfsd->nd_md, &nfsd->nd_dpos, s, avail, &ret);
+	if (error != 0) {
+		m_freem(nfsd->nd_mrep);
+		nfsd->nd_mrep = NULL;
+		*errorp = error;
+		return NULL;
+	} else {
+		return ret;
+	}
+}
+
+static inline void *
 nfsm_dissect(struct nfsm_info *infop, int s)
 {
 	caddr_t ret;
@@ -83,6 +106,27 @@ nfsm_dissect(struct nfsm_info *infop, in
 #define nfsm_rndup(a)	(((a)+3)&(~0x3))
 
 static inline int
+nfsd_adv(struct nfsrv_descript *nfsd, int s, int *errorp)
+{
+	int avail, error;
+       
+	avail = mtod(nfsd->nd_md, caddr_t) + nfsd->nd_md->m_len -
+	    nfsd->nd_dpos;
+	if (avail >= s) {
+		nfsd->nd_dpos += s;
+		return 0;
+	}
+	error = nfs_adv(&nfsd->nd_md, &nfsd->nd_dpos, s, avail);
+	if (error != 0) {
+		m_freem(nfsd->nd_mrep);
+		nfsd->nd_mrep = NULL;
+		*errorp = error;
+		return error;
+	}
+	return 0;
+}
+
+static inline int
 nfsm_adv(struct nfsm_info *infop, int s)
 {
 	int avail, error;
@@ -134,6 +178,24 @@ nfsm_postop_attr(struct nfsm_info *infop
 }
 
 static inline int
+nfsd_strsiz(struct nfsrv_descript *nfsd, int *lenp, int maxlen, int *errorp)
+{
+	uint32_t *tl = (uint32_t *)nfsd_dissect(nfsd, NFSX_UNSIGNED, errorp);
+	int len;
+	if (tl == NULL)
+		return 1;
+	len = fxdr_unsigned(int32_t, *tl);
+	if (len < 0 || len > maxlen) {
+		m_freem(nfsd->nd_mrep);
+		nfsd->nd_mrep = NULL;
+		*errorp = EBADRPC;
+		return 1;
+	}
+	*lenp = len;
+	return 0;
+}
+
+static inline int
 nfsm_strsiz(struct nfsm_info *infop, int *lenp, int maxlen)
 {
 	uint32_t *tl = (uint32_t *)nfsm_dissect(infop, NFSX_UNSIGNED);
@@ -152,6 +214,24 @@ nfsm_strsiz(struct nfsm_info *infop, int
 }
 
 static inline int
+nfsd_mtouio(struct nfsrv_descript *nfsd, struct uio *uiop, int len, int *errorp)
+{
+	int error;
+
+	if (len <= 0)
+		return 0;
+
+	error = nfsm_mbuftouio(&nfsd->nd_md, uiop, len, &nfsd->nd_dpos);
+	if (error != 0) {
+		m_freem(nfsd->nd_mrep);
+		nfsd->nd_mrep = NULL;
+		*errorp = error;
+		return error;
+	}
+	return 0;
+}
+
+static inline int
 nfsm_mtouio(struct nfsm_info *infop, struct uio *uiop, int len)
 {
 	int error;
@@ -170,7 +250,8 @@ nfsm_mtouio(struct nfsm_info *infop, str
 }
 
 static inline int
-nfsm_strtom(struct nfsm_info *infop, char *str, size_t len, size_t maxlen)
+nfsm_strtom(struct nfsm_info *infop, struct mbuf **mb,
+    char *str, size_t len, size_t maxlen)
 {
 	if (len > maxlen) {
 		m_freem(infop->nmi_mreq);
@@ -178,7 +259,7 @@ nfsm_strtom(struct nfsm_info *infop, cha
 		*infop->nmi_errorp = ENAMETOOLONG;
 		return 1;
 	}
-	nfsm_strtombuf(&infop->nmi_mb, str, len);
+	nfsm_strtombuf(mb, str, len);
 	return 0;
 }
 
