Convert all the NFS macros (in nfsm_subs.h) into inline functions with the
authormiod <miod@openbsd.org>
Tue, 30 Apr 2024 17:04:23 +0000 (17:04 +0000)
committermiod <miod@openbsd.org>
Tue, 30 Apr 2024 17:04:23 +0000 (17:04 +0000)
appropriate extra arguments.

This (hopefully) completes the unmessyfication work started by thib@ a long,
long time ago (in a galaxy far away).

The conversion logic has been:
- nfsm_dissect has been turned into an rvalue expression, leaving the
  cast operation up to its caller.
- macros which had three different exit paths (return, goto nfsmout or
  fallthrough) have been split so that no macros have more than two exit paths.
- then they have been modified to return a value, which lets the caller
  figure out what exit path is needed.
- local variables abused by the macros are now local variables of the new
  inline functions.

This single commit is the sum of 25 intermediate diffs, which have all been
carefully reviewed by (at least) jsg@ and semarie@.

Tested with v2 and v3 servers and clients.

ok jsg@ semarie@

sys/nfs/nfs_serv.c
sys/nfs/nfs_socket.c
sys/nfs/nfs_subs.c
sys/nfs/nfs_var.h
sys/nfs/nfs_vfsops.c
sys/nfs/nfs_vnops.c
sys/nfs/nfsm_subs.h
sys/nfs/nfsnode.h

index 2f4624c..c637ac8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: nfs_serv.c,v 1.123 2024/03/25 17:57:07 guenther Exp $ */
+/*     $OpenBSD: nfs_serv.c,v 1.124 2024/04/30 17:04:23 miod Exp $     */
 /*     $NetBSD: nfs_serv.c,v 1.34 1997/05/12 23:37:12 fvdl Exp $       */
 
 /*
  *       (surprisingly ?? many are very similar to syscalls in vfs_syscalls.c)
  *   3 - build the rpc reply in an mbuf list
  *   nb:
- *     - do not mix the phases, since the nfsm_?? macros can return failures
- *       on a bad rpc or similar and do not do any vrele() or vput()'s
- *
- *      - the nfsm_reply() macro generates an nfs rpc reply with the nfs
- *     error number iff error != 0 whereas
- *     returning an error from the server function implies a fatal error
- *     such as a badly constructed rpc request that should be dropped without
- *     a reply.
- *     For Version 3, nfsm_reply() does not return for the error case, since
- *     most version 3 rpcs return more than the status for error cases.
+ *     - do not mix the phases, since use of the nfsm_?? functions can cause
+ *       us to return failures on a bad rpc or similar without doing any
+ *       vrele() or vput()'s
+ *      - the nfsm_reply() function generates an nfs rpc reply with the nfs
+ *       error number iff error != 0 whereas returning an error from the
+ *       server function implies a fatal error such as a badly constructed rpc
+ *       request that should be dropped without a reply.
+ *     For Version 3, we do not return after nfsm_reply() for the error case,
+ *     since most version 3 rpcs return more than the status for error cases.
  */
 
 #include <sys/param.h>
@@ -77,8 +76,8 @@
 #include <nfs/nfsproto.h>
 #include <nfs/nfs.h>
 #include <nfs/xdr_subs.h>
-#include <nfs/nfsm_subs.h>
 #include <nfs/nfs_var.h>
+#include <nfs/nfsm_subs.h>
 
 /* Global vars */
 extern u_int32_t nfs_xdrneg1;
@@ -90,6 +89,56 @@ extern nfstype nfsv3_type[9];
 
 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)
+{
+       nfsd->nd_repstat = error;
+       if (error && !infop->nmi_v3)
+               statuslen = 0;
+       (void)nfs_rephead(statuslen, nfsd, slp, error,
+               &infop->nmi_mreq, &infop->nmi_mb);
+       if (infop->nmi_mrep != NULL) {
+               m_freem(infop->nmi_mrep);
+               infop->nmi_mrep = NULL;
+       }
+       *mrq = infop->nmi_mreq;
+       if (error && (!infop->nmi_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);
+               if (tl == NULL)
+                       return 0; /* *infop->nmi_errorp set */
+               if (fxdr_unsigned(int, *tl) != NFSX_V3FH) {
+                       *infop->nmi_errorp = EBADRPC;
+                       return nfsm_reply(infop, nfsd, slp, mrq,
+                           *infop->nmi_errorp, 0);
+               }
+       }
+       return 0;
+}
+
+static inline int
+nfsm_srvmtofh2(struct nfsm_info *infop, fhandle_t *fhp)
+{
+       uint32_t *tl = (uint32_t *)nfsm_dissect(infop, NFSX_V3FH);
+       if (tl == NULL)
+               return 1;
+       bcopy(tl, fhp, NFSX_V3FH);
+       if (infop->nmi_v3 == 0) {
+               if (nfsm_adv(infop, NFSX_V2FH - NFSX_V3FH) != 0)
+                       return 1;
+       }
+       return 0;
+}
+
 /*
  * nfs v3 access service
  */
@@ -104,9 +153,7 @@ nfsrv3_access(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        nfsfh_t nfh;
        fhandle_t *fhp;
        u_int32_t *tl;
-       int32_t t1;
        int error = 0, rdonly, getret;
-       char *cp2;
        struct vattr va;
        u_long testmode, nfsmode;
 
@@ -114,13 +161,24 @@ nfsrv3_access(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        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)
+               return 0;
+       else if (error != 0)
+               goto nfsmout;
        fhp = &nfh.fh_generic;
-       nfsm_srvmtofh(fhp);
-       nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
+       if (nfsm_srvmtofh2(&info, fhp) != 0)
+               goto nfsmout;
+       tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+       if (tl == NULL)
+               goto nfsmout;
        error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
        if (error) {
-               nfsm_reply(NFSX_UNSIGNED);
+               if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                   NFSX_UNSIGNED) != 0)
+                       return 0;
                nfsm_srvpostop_attr(nfsd, 1, NULL, &info);
                error = 0;
                goto nfsmout;
@@ -146,7 +204,9 @@ nfsrv3_access(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
                nfsmode &= ~testmode;
        getret = VOP_GETATTR(vp, &va, cred, procp);
        vput(vp);
-       nfsm_reply(NFSX_POSTOPATTR(1) + NFSX_UNSIGNED);
+       if (nfsm_reply(&info, nfsd, slp, mrq, error,
+           NFSX_POSTOPATTR(1) + NFSX_UNSIGNED) != 0)
+               return 0;
        nfsm_srvpostop_attr(nfsd, getret, &va, &info);
        tl = nfsm_build(&info.nmi_mb, NFSX_UNSIGNED);
        *tl = txdr_unsigned(nfsmode);
@@ -169,28 +229,34 @@ nfsrv_getattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        struct vnode *vp;
        nfsfh_t nfh;
        fhandle_t *fhp;
-       u_int32_t *tl;
-       int32_t t1;
        int error = 0, rdonly;
-       char *cp2;
 
        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)
+               return 0;
+       else if (error != 0)
+               goto nfsmout;
        fhp = &nfh.fh_generic;
-       nfsm_srvmtofh(fhp);
+       if (nfsm_srvmtofh2(&info, fhp) != 0)
+               goto nfsmout;
        error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
        if (error) {
-               nfsm_reply(0);
+               if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0)
+                       return 0;
                error = 0;
                goto nfsmout;
        }
        error = VOP_GETATTR(vp, &va, cred, procp);
        vput(vp);
-       nfsm_reply(NFSX_FATTR(nfsd->nd_flag & ND_NFSV3));
+       if (nfsm_reply(&info, nfsd, slp, mrq, error,
+           NFSX_FATTR(nfsd->nd_flag & ND_NFSV3)) != 0)
+               return 0;
        if (error) {
                error = 0;
                goto nfsmout;
@@ -218,10 +284,8 @@ nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        nfsfh_t nfh;
        fhandle_t *fhp;
        u_int32_t *tl;
-       int32_t t1;
        int error = 0, rdonly, preat_ret = 1, postat_ret = 1;
        int gcheck = 0;
-       char *cp2;
        struct timespec guard;
 
        info.nmi_mreq = NULL;
@@ -229,23 +293,35 @@ nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        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)
+               return 0;
+       else if (error != 0)
+               goto nfsmout;
        fhp = &nfh.fh_generic;
-       nfsm_srvmtofh(fhp);
+       if (nfsm_srvmtofh2(&info, fhp) != 0)
+               goto nfsmout;
        VATTR_NULL(&va);
        if (info.nmi_v3) {
                va.va_vaflags |= VA_UTIMES_NULL;
                error = nfsm_srvsattr(&info.nmi_md, &va, info.nmi_mrep, &info.nmi_dpos);
                if (error)
                        goto nfsmout;
-               nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
+               tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+               if (tl == NULL)
+                       goto nfsmout;
                gcheck = fxdr_unsigned(int, *tl);
                if (gcheck) {
-                       nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
+                       tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED);
+                       if (tl == NULL)
+                               goto nfsmout;
                        fxdr_nfsv3time(tl, &guard);
                }
        } else {
-               nfsm_dissect(sp, struct nfsv2_sattr *, NFSX_V2SATTR);
+               sp = (struct nfsv2_sattr *)nfsm_dissect(&info, NFSX_V2SATTR);
+               if (sp == NULL)
+                       goto nfsmout;
                /*
                 * Nah nah nah nah na nah
                 * There is a bug in the Sun client that puts 0xffff in the mode
@@ -280,7 +356,9 @@ nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
         */
        error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
        if (error) {
-               nfsm_reply(2 * NFSX_UNSIGNED);
+               if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                   2 * NFSX_UNSIGNED) != 0)
+                       return 0;
                nfsm_srvwcc(nfsd, preat_ret, &preat, postat_ret, &va, &info);
                error = 0;
                goto nfsmout;
@@ -293,7 +371,9 @@ nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
                        error = NFSERR_NOT_SYNC;
                if (error) {
                        vput(vp);
-                       nfsm_reply(NFSX_WCCDATA(info.nmi_v3));
+                       if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                           NFSX_WCCDATA(info.nmi_v3)) != 0)
+                               return 0;
                        nfsm_srvwcc(nfsd, preat_ret, &preat, postat_ret, &va,
                            &info);
                        error = 0;
@@ -324,7 +404,9 @@ nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
                error = postat_ret;
 out:
        vput(vp);
-       nfsm_reply(NFSX_WCCORFATTR(info.nmi_v3));
+       if (nfsm_reply(&info, nfsd, slp, mrq, error,
+           NFSX_WCCORFATTR(info.nmi_v3)) != 0)
+               return 0;
        if (info.nmi_v3) {
                nfsm_srvwcc(nfsd, preat_ret, &preat, postat_ret, &va,
                    &info);
@@ -338,6 +420,25 @@ nfsmout:
        return(error);
 }
 
+static inline int
+nfsm_srvnamesiz(struct nfsm_info *infop, int *lenp)
+{
+       int len;
+       uint32_t *tl = (uint32_t *)nfsm_dissect(infop, NFSX_UNSIGNED);
+       if (tl == NULL)
+               return 1;
+       len = fxdr_unsigned(int32_t, *tl);
+       if (len > NFS_MAXNAMLEN)
+               *infop->nmi_errorp = NFSERR_NAMETOL;
+       else if (len <= 0)
+               *infop->nmi_errorp = EBADRPC;
+       else {
+               *infop->nmi_errorp = 0;
+               *lenp = len;
+       }
+       return 0;
+}
+
 /*
  * nfs lookup rpc
  */
@@ -353,11 +454,8 @@ nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        struct nfsm_info        info;
        nfsfh_t nfh;
        fhandle_t *fhp;
-       u_int32_t *tl;
-       int32_t t1;
        int error = 0, len, dirattr_ret = 1;
        int v3 = (nfsd->nd_flag & ND_NFSV3);
-       char *cp2;
        struct vattr va, dirattr;
 
        info.nmi_mrep = nfsd->nd_mrep;
@@ -365,10 +463,21 @@ nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        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)
+               return 0;
+       else if (error != 0)
+               goto nfsmout;
        fhp = &nfh.fh_generic;
-       nfsm_srvmtofh(fhp);
-       nfsm_srvnamesiz(len);
+       if (nfsm_srvmtofh2(&info, fhp) != 0)
+               goto nfsmout;
+       if (nfsm_srvnamesiz(&info, &len) != 0)
+               goto nfsmout;
+       if (error) {
+               if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0)
+                       return 0;
+       }
 
        NDINIT(&nd, LOOKUP, LOCKLEAF | SAVESTART, UIO_SYSSPACE, NULL, procp);
        nd.ni_cnd.cn_cred = cred;
@@ -380,7 +489,9 @@ nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
                vrele(dirp);
        }
        if (error) {
-               nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3));
+               if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                   NFSX_POSTOPATTR(info.nmi_v3)) != 0)
+                       return 0;
                nfsm_srvpostop_attr(nfsd, dirattr_ret, &dirattr, &info);
                return (0);
        }
@@ -393,8 +504,10 @@ nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        if (!error)
                error = VOP_GETATTR(vp, &va, cred, procp);
        vput(vp);
-       nfsm_reply(NFSX_SRVFH(info.nmi_v3) + NFSX_POSTOPORFATTR(info.nmi_v3)
-           + NFSX_POSTOPATTR(info.nmi_v3));
+       if (nfsm_reply(&info, nfsd, slp, mrq, error,
+           NFSX_SRVFH(info.nmi_v3) + NFSX_POSTOPORFATTR(info.nmi_v3) +
+           NFSX_POSTOPATTR(info.nmi_v3)) != 0)
+               return 0;
        if (error) {
                nfsm_srvpostop_attr(nfsd, dirattr_ret, &dirattr, &info);
                error = 0;
@@ -425,9 +538,7 @@ nfsrv_readlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        struct mbuf *mp = NULL;
        struct nfsm_info        info;
        u_int32_t *tl;
-       int32_t t1;
        int error = 0, rdonly, tlen, len = 0, getret;
-       char *cp2;
        struct vnode *vp;
        struct vattr attr;
        nfsfh_t nfh;
@@ -439,14 +550,22 @@ nfsrv_readlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        info.nmi_md = nfsd->nd_md;
        info.nmi_dpos = nfsd->nd_dpos;
        info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
+       info.nmi_errorp = &error;
 
        memset(&uio, 0, sizeof(uio));
 
+       if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+               return 0;
+       else if (error != 0)
+               goto nfsmout;
        fhp = &nfh.fh_generic;
-       nfsm_srvmtofh(fhp);
+       if (nfsm_srvmtofh2(&info, fhp) != 0)
+               goto nfsmout;
        error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
        if (error) {
-               nfsm_reply(2 * NFSX_UNSIGNED);
+               if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                   2 * NFSX_UNSIGNED) != 0)
+                       return 0;
                nfsm_srvpostop_attr(nfsd, 1, NULL, &info);
                error = 0;
                goto nfsmout;
@@ -480,7 +599,9 @@ out:
        vput(vp);
        if (error)
                m_freem(mp);
-       nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3) + NFSX_UNSIGNED);
+       if (nfsm_reply(&info, nfsd, slp, mrq, error,
+           NFSX_POSTOPATTR(info.nmi_v3) + NFSX_UNSIGNED) != 0)
+               return 0;
        if (info.nmi_v3) {
                nfsm_srvpostop_attr(nfsd, getret, &attr, &info);
                if (error) {
@@ -514,10 +635,8 @@ nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        struct nfs_fattr *fp;
        struct nfsm_info        info;
        u_int32_t *tl;
-       int32_t t1;
        int i, reqlen;
        int error = 0, rdonly, cnt, len, left, siz, tlen, getret = 1;
-       char *cp2;
        struct mbuf *m2;
        struct vnode *vp;
        nfsfh_t nfh;
@@ -531,22 +650,35 @@ nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        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)
+               return 0;
+       else if (error != 0)
+               goto nfsmout;
        fhp = &nfh.fh_generic;
-       nfsm_srvmtofh(fhp);
+       if (nfsm_srvmtofh2(&info, fhp) != 0)
+               goto nfsmout;
        if (info.nmi_v3) {
-               nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
+               tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED);
+               if (tl == NULL)
+                       goto nfsmout;
                off = fxdr_hyper(tl);
        } else {
-               nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
+               tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+               if (tl == NULL)
+                       goto nfsmout;
                off = (off_t)fxdr_unsigned(u_int32_t, *tl);
        }
 
-       nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
+       tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+       if (tl == NULL)
+               goto nfsmout;
        reqlen = fxdr_unsigned(int32_t, *tl);
        if (reqlen > (NFS_SRVMAXDATA(nfsd)) || reqlen <= 0) {
                error = EBADRPC;
-               nfsm_reply(0);
+               if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0)
+                       return 0;
        }
 
        error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
@@ -575,7 +707,10 @@ nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
                cnt = va.va_size - off;
        else
                cnt = reqlen;
-       nfsm_reply(NFSX_POSTOPORFATTR(info.nmi_v3) + 3 * NFSX_UNSIGNED+nfsm_rndup(cnt));
+       if (nfsm_reply(&info, nfsd, slp, mrq, error,
+           NFSX_POSTOPORFATTR(info.nmi_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);
                *tl++ = nfs_true;
@@ -667,7 +802,8 @@ nfsmout:
 vbad:
        vput(vp);
 bad:
-       nfsm_reply(0);
+       if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0)
+               return 0;
        nfsm_srvpostop_attr(nfsd, getret, &va, &info);
        return (0);
 }
@@ -688,11 +824,9 @@ nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        struct timeval boottime;
        struct vattr va, forat;
        u_int32_t *tl;
-       int32_t t1;
        int error = 0, rdonly, len, forat_ret = 1;
        int ioflags, aftat_ret = 1, retlen, zeroing, adjust;
        int stable = NFSV3WRITE_FILESYNC;
-       char *cp2;
        struct vnode *vp;
        nfsfh_t nfh;
        fhandle_t *fhp;
@@ -704,20 +838,30 @@ nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        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 (info.nmi_mrep == NULL) {
                *mrq = NULL;
                return (0);
        }
+       if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+               return 0;
+       else if (error != 0)
+               goto nfsmout;
        fhp = &nfh.fh_generic;
-       nfsm_srvmtofh(fhp);
+       if (nfsm_srvmtofh2(&info, fhp) != 0)
+               goto nfsmout;
        if (info.nmi_v3) {
-               nfsm_dissect(tl, u_int32_t *, 5 * NFSX_UNSIGNED);
+               tl = (uint32_t *)nfsm_dissect(&info, 5 * NFSX_UNSIGNED);
+               if (tl == NULL)
+                       goto nfsmout;
                off = fxdr_hyper(tl);
                tl += 3;
                stable = fxdr_unsigned(int, *tl++);
        } else {
-               nfsm_dissect(tl, u_int32_t *, 4 * NFSX_UNSIGNED);
+               tl = (uint32_t *)nfsm_dissect(&info, 4 * NFSX_UNSIGNED);
+               if (tl == NULL)
+                       goto nfsmout;
                off = (off_t)fxdr_unsigned(u_int32_t, *++tl);
                tl += 2;
        }
@@ -811,8 +955,10 @@ nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        vput(vp);
        if (!error)
                error = aftat_ret;
-       nfsm_reply(NFSX_PREOPATTR(info.nmi_v3) + NFSX_POSTOPORFATTR(info.nmi_v3) +
-               2 * NFSX_UNSIGNED + NFSX_WRITEVERF(info.nmi_v3));
+       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)
+               return 0;
        if (info.nmi_v3) {
                nfsm_srvwcc(nfsd, forat_ret, &forat, aftat_ret, &va, &info);
                if (error) {
@@ -843,11 +989,23 @@ nfsmout:
 vbad:
        vput(vp);
 bad:
-       nfsm_reply(0);
+       if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0)
+               return 0;
        nfsm_srvwcc(nfsd, forat_ret, &forat, aftat_ret, &va, &info);
        return (0);
 }
 
+static inline void
+nfsm_srvpostop_fh(struct nfsm_info *infop, fhandle_t *fhp)
+{
+       uint32_t *tl;
+
+       tl = nfsm_build(&infop->nmi_mb, 2 * NFSX_UNSIGNED + NFSX_V3FH);
+       *tl++ = nfs_true;
+       *tl++ = txdr_unsigned(NFSX_V3FH);
+       bcopy(fhp, tl, NFSX_V3FH);
+}
+
 /*
  * nfs create service
  * now does a truncate to 0 length via. setattr if it already exists
@@ -865,11 +1023,9 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        u_int32_t *tl;
        struct nameidata nd;
        caddr_t cp;
-       int32_t t1;
        int error = 0, len, tsize, dirfor_ret = 1, diraft_ret = 1;
        dev_t rdev = 0;
        int how, exclusive_flag = 0;
-       char *cp2;
        struct vnode *vp = NULL, *dirp = NULL;
        nfsfh_t nfh;
        fhandle_t *fhp;
@@ -881,10 +1037,21 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        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)
+               return 0;
+       else if (error != 0)
+               goto nfsmout;
        fhp = &nfh.fh_generic;
-       nfsm_srvmtofh(fhp);
-       nfsm_srvnamesiz(len);
+       if (nfsm_srvmtofh2(&info, fhp) != 0)
+               goto nfsmout;
+       if (nfsm_srvnamesiz(&info, &len) != 0)
+               goto nfsmout;
+       if (error) {
+               if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0)
+                       return 0;
+       }
 
        NDINIT(&nd, CREATE, LOCKPARENT | LOCKLEAF | SAVESTART, UIO_SYSSPACE,
            NULL, procp);
@@ -900,7 +1067,9 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
                }
        }
        if (error) {
-               nfsm_reply(NFSX_WCCDATA(info.nmi_v3));
+               if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                   NFSX_WCCDATA(info.nmi_v3)) != 0)
+                       return 0;
                nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
                    &info);
                if (dirp)
@@ -910,7 +1079,9 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
 
        VATTR_NULL(&va);
        if (info.nmi_v3) {
-               nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
+               tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+               if (tl == NULL)
+                       goto nfsmout;
                how = fxdr_unsigned(int, *tl);
                switch (how) {
                case NFSV3CREATE_GUARDED:
@@ -925,7 +1096,9 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
                                goto nfsmout;
                        break;
                case NFSV3CREATE_EXCLUSIVE:
-                       nfsm_dissect(cp, caddr_t, NFSX_V3CREATEVERF);
+                       cp = (caddr_t)nfsm_dissect(&info, NFSX_V3CREATEVERF);
+                       if (cp == NULL)
+                               goto nfsmout;
                        bcopy(cp, cverf, NFSX_V3CREATEVERF);
                        exclusive_flag = 1;
                        if (nd.ni_vp == NULL)
@@ -934,7 +1107,9 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
                };
                va.va_type = VREG;
        } else {
-               nfsm_dissect(sp, struct nfsv2_sattr *, NFSX_V2SATTR);
+               sp = (struct nfsv2_sattr *)nfsm_dissect(&info, NFSX_V2SATTR);
+               if (sp == NULL)
+                       goto nfsmout;
                va.va_type = IFTOVT(fxdr_unsigned(u_int32_t, sp->sa_mode));
                if (va.va_type == VNON)
                        va.va_type = VREG;
@@ -990,7 +1165,9 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
                                }
                                VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
                                vput(nd.ni_dvp);
-                               nfsm_reply(0);
+                               if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                                   0) != 0)
+                                       return 0;
                                error = 0;
                                goto nfsmout;
                        } else
@@ -1004,7 +1181,9 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
                                        pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
                                        nd.ni_cnd.cn_flags &= ~HASBUF;
                                }
-                               nfsm_reply(0);
+                               if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                                   0) != 0)
+                                       return 0;
                                error = 0;
                                goto nfsmout;
                        }
@@ -1017,7 +1196,9 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
                                        pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf);
                                        nd.ni_cnd.cn_flags &= ~HASBUF;
                                }
-                               nfsm_reply(0);
+                               if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                                   0) != 0)
+                                       return 0;
                                error = 0;
                                goto nfsmout;
                        }
@@ -1028,7 +1209,9 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
                                vput(nd.ni_vp);
                                VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
                                error = EINVAL;
-                               nfsm_reply(0);
+                               if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                                   0) != 0)
+                                       return 0;
                                error = 0;
                                goto nfsmout;
                        }
@@ -1080,11 +1263,12 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
                diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp);
                vrele(dirp);
        }
-       nfsm_reply(NFSX_SRVFH(info.nmi_v3) + NFSX_FATTR(info.nmi_v3)
-           + NFSX_WCCDATA(info.nmi_v3));
+       if (nfsm_reply(&info, nfsd, slp, mrq, error, NFSX_SRVFH(info.nmi_v3) +
+           NFSX_FATTR(info.nmi_v3) + NFSX_WCCDATA(info.nmi_v3)) != 0)
+               return 0;
        if (info.nmi_v3) {
                if (!error) {
-                       nfsm_srvpostop_fh(fhp);
+                       nfsm_srvpostop_fh(&info, fhp);
                        nfsm_srvpostop_attr(nfsd, 0, &va, &info);
                }
                nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
@@ -1128,11 +1312,9 @@ nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        struct nfsm_info        info;
        u_int32_t *tl;
        struct nameidata nd;
-       int32_t t1;
        int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
        u_int32_t major, minor;
        enum vtype vtyp;
-       char *cp2;
        struct vnode *vp, *dirp = NULL;
        nfsfh_t nfh;
        fhandle_t *fhp;
@@ -1142,10 +1324,21 @@ nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        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)
+               return 0;
+       else if (error != 0)
+               goto nfsmout;
        fhp = &nfh.fh_generic;
-       nfsm_srvmtofh(fhp);
-       nfsm_srvnamesiz(len);
+       if (nfsm_srvmtofh2(&info, fhp) != 0)
+               goto nfsmout;
+       if (nfsm_srvnamesiz(&info, &len) != 0)
+               goto nfsmout;
+       if (error) {
+               if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0)
+                       return 0;
+       }
 
        NDINIT(&nd, CREATE, LOCKPARENT | LOCKLEAF | SAVESTART, UIO_SYSSPACE,
            NULL, procp);
@@ -1154,7 +1347,9 @@ nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        if (dirp)
                dirfor_ret = VOP_GETATTR(dirp, &dirfor, cred, procp);
        if (error) {
-               nfsm_reply(NFSX_WCCDATA(1));
+               if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                   NFSX_WCCDATA(1)) != 0)
+                       return 0;
                nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
                    &info);
                if (dirp)
@@ -1162,7 +1357,9 @@ nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
                return (0);
        }
 
-       nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
+       tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+       if (tl == NULL)
+               goto nfsmout;
        vtyp = nfsv3tov_type(*tl);
        if (vtyp != VCHR && vtyp != VBLK && vtyp != VSOCK && vtyp != VFIFO) {
                vrele(nd.ni_startdir);
@@ -1182,7 +1379,9 @@ nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        if (error)
                goto nfsmout;
        if (vtyp == VCHR || vtyp == VBLK) {
-               nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
+               tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED);
+               if (tl == NULL)
+                       goto nfsmout;
                major = fxdr_unsigned(u_int32_t, *tl++);
                minor = fxdr_unsigned(u_int32_t, *tl);
                va.va_rdev = makedev(major, minor);
@@ -1252,9 +1451,11 @@ out:
        }
        diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp);
        vrele(dirp);
-       nfsm_reply(NFSX_SRVFH(1) + NFSX_POSTOPATTR(1) + NFSX_WCCDATA(1));
+       if (nfsm_reply(&info, nfsd, slp, mrq, error,
+           NFSX_SRVFH(1) + NFSX_POSTOPATTR(1) + NFSX_WCCDATA(1)) != 0)
+               return 0;
        if (!error) {
-               nfsm_srvpostop_fh(fhp);
+               nfsm_srvpostop_fh(&info, fhp);
                nfsm_srvpostop_attr(nfsd, 0, &va, &info);
        }
        nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft, &info);
@@ -1287,10 +1488,7 @@ nfsrv_remove(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        struct ucred *cred = &nfsd->nd_cr;
        struct nameidata nd;
        struct nfsm_info        info;
-       u_int32_t *tl;
-       int32_t t1;
        int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
-       char *cp2;
        struct vnode *vp, *dirp;
        struct vattr dirfor, diraft;
        nfsfh_t nfh;
@@ -1301,12 +1499,23 @@ nfsrv_remove(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        info.nmi_md = nfsd->nd_md;
        info.nmi_dpos = nfsd->nd_dpos;
        info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
+       info.nmi_errorp = &error;
 
        vp = NULL;
 
+       if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+               return 0;
+       else if (error != 0)
+               goto nfsmout;
        fhp = &nfh.fh_generic;
-       nfsm_srvmtofh(fhp);
-       nfsm_srvnamesiz(len);
+       if (nfsm_srvmtofh2(&info, fhp) != 0)
+               goto nfsmout;
+       if (nfsm_srvnamesiz(&info, &len) != 0)
+               goto nfsmout;
+       if (error) {
+               if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0)
+                       return 0;
+       }
 
        NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_SYSSPACE, NULL, procp);
        nd.ni_cnd.cn_cred = cred;
@@ -1350,7 +1559,9 @@ out:
                diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp);
                vrele(dirp);
        }
-       nfsm_reply(NFSX_WCCDATA(info.nmi_v3));
+       if (nfsm_reply(&info, nfsd, slp, mrq, error,
+           NFSX_WCCDATA(info.nmi_v3)) != 0)
+               return 0;
        if (info.nmi_v3) {
                nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
                    &info);
@@ -1371,11 +1582,8 @@ nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        struct mbuf *nam = nfsd->nd_nam;
        struct ucred *cred = &nfsd->nd_cr;
        struct nfsm_info        info;
-       u_int32_t *tl;
-       int32_t t1;
        int error = 0, len, len2, fdirfor_ret = 1, fdiraft_ret = 1;
        int tdirfor_ret = 1, tdiraft_ret = 1;
-       char *cp2;
        struct nameidata fromnd, tond;
        struct vnode *fvp = NULL, *tvp, *tdvp, *fdirp = NULL;
        struct vnode *tdirp = NULL;
@@ -1389,11 +1597,21 @@ nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        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)
+               return 0;
+       else if (error != 0)
+               goto nfsmout;
        ffhp = &fnfh.fh_generic;
-       tfhp = &tnfh.fh_generic;
-       nfsm_srvmtofh(ffhp);
-       nfsm_srvnamesiz(len);
+       if (nfsm_srvmtofh2(&info, ffhp) != 0)
+               goto nfsmout;
+       if (nfsm_srvnamesiz(&info, &len) != 0)
+               goto nfsmout;
+       if (error) {
+               if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0)
+                       return 0;
+       }
 
        /*
         * Remember our original uid so that we can reset cr_uid before
@@ -1416,7 +1634,9 @@ nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
                }
        }
        if (error) {
-               nfsm_reply(2 * NFSX_WCCDATA(info.nmi_v3));
+               if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                   2 * NFSX_WCCDATA(info.nmi_v3)) != 0)
+                       return 0;
                nfsm_srvwcc(nfsd, fdirfor_ret, &fdirfor, fdiraft_ret, &fdiraft,
                    &info);
                nfsm_srvwcc(nfsd, tdirfor_ret, &tdirfor, tdiraft_ret, &tdiraft,
@@ -1427,8 +1647,15 @@ nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        }
 
        fvp = fromnd.ni_vp;
-       nfsm_srvmtofh(tfhp);
-       nfsm_strsiz(len2, NFS_MAXNAMLEN);
+       if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+               return 0;
+       else if (error != 0)
+               goto nfsmout;
+       tfhp = &tnfh.fh_generic;
+       if (nfsm_srvmtofh2(&info, tfhp) != 0)
+               goto nfsmout;
+       if (nfsm_strsiz(&info, &len2, NFS_MAXNAMLEN) != 0)
+               goto nfsmout;
        cred->cr_uid = saved_uid;
 
        NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF| NOCACHE | SAVESTART,
@@ -1520,7 +1747,9 @@ out1:
        }
        vrele(fromnd.ni_startdir);
        pool_put(&namei_pool, fromnd.ni_cnd.cn_pnbuf);
-       nfsm_reply(2 * NFSX_WCCDATA(info.nmi_v3));
+       if (nfsm_reply(&info, nfsd, slp, mrq, error,
+           2 * NFSX_WCCDATA(info.nmi_v3)) != 0)
+               return 0;
        if (info.nmi_v3) {
                nfsm_srvwcc(nfsd, fdirfor_ret, &fdirfor, fdiraft_ret, &fdiraft,
                    &info);
@@ -1566,11 +1795,8 @@ nfsrv_link(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        struct nfsm_info        info;
        struct ucred *cred = &nfsd->nd_cr;
        struct nameidata nd;
-       u_int32_t *tl;
-       int32_t t1;
        int error = 0, rdonly, len, dirfor_ret = 1, diraft_ret = 1;
        int getret = 1;
-       char *cp2;
        struct vnode *vp, *xp, *dirp = NULL;
        struct vattr dirfor, diraft, at;
        nfsfh_t nfh, dnfh;
@@ -1581,17 +1807,35 @@ nfsrv_link(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        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)
+               return 0;
+       else if (error != 0)
+               goto nfsmout;
        fhp = &nfh.fh_generic;
+       if (nfsm_srvmtofh2(&info, fhp) != 0)
+               goto nfsmout;
+       if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0)
+               return 0;
+       else if (error != 0)
+               goto nfsmout;
        dfhp = &dnfh.fh_generic;
-       nfsm_srvmtofh(fhp);
-       nfsm_srvmtofh(dfhp);
-       nfsm_srvnamesiz(len);
+       if (nfsm_srvmtofh2(&info, dfhp) != 0)
+               goto nfsmout;
+       if (nfsm_srvnamesiz(&info, &len) != 0)
+               goto nfsmout;
+       if (error) {
+               if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0)
+                       return 0;
+       }
 
        error = nfsrv_fhtovp(fhp, 0, &vp, cred, slp, nam, &rdonly);
        if (error) {
-               nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3) +
-                   NFSX_WCCDATA(info.nmi_v3));
+               if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                   NFSX_POSTOPATTR(info.nmi_v3) +
+                   NFSX_WCCDATA(info.nmi_v3)) != 0)
+                       return 0;
                nfsm_srvpostop_attr(nfsd, getret, &at, &info);
                nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
                    &info);
@@ -1644,7 +1888,9 @@ out1:
                vrele(dirp);
        }
        vrele(vp);
-       nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3) + NFSX_WCCDATA(info.nmi_v3));
+       if (nfsm_reply(&info, nfsd, slp, mrq, error,
+           NFSX_POSTOPATTR(info.nmi_v3) + NFSX_WCCDATA(info.nmi_v3)) != 0)
+               return 0;
        if (info.nmi_v3) {
                nfsm_srvpostop_attr(nfsd, getret, &at, &info);
                nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
@@ -1667,10 +1913,8 @@ nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        struct vattr va, dirfor, diraft;
        struct nameidata nd;
        struct nfsm_info        info;
-       u_int32_t *tl;
-       int32_t t1;
        struct nfsv2_sattr *sp;
-       char *pathcp = NULL, *cp2;
+       char *pathcp = NULL;
        struct uio io;
        struct iovec iv;
        int error = 0, len, pathlen, len2, dirfor_ret = 1, diraft_ret = 1;
@@ -1683,10 +1927,21 @@ nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        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)
+               return 0;
+       else if (error != 0)
+               goto nfsmout;
        fhp = &nfh.fh_generic;
-       nfsm_srvmtofh(fhp);
-       nfsm_srvnamesiz(len);
+       if (nfsm_srvmtofh2(&info, fhp) != 0)
+               goto nfsmout;
+       if (nfsm_srvnamesiz(&info, &len) != 0)
+               goto nfsmout;
+       if (error) {
+               if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0)
+                       return 0;
+       }
 
        NDINIT(&nd, CREATE, LOCKPARENT | SAVESTART, UIO_SYSSPACE, NULL, procp);
        nd.ni_cnd.cn_cred = cred;
@@ -1710,7 +1965,8 @@ nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
                if (error)
                        goto nfsmout;
        }
-       nfsm_strsiz(len2, NFS_MAXPATHLEN);
+       if (nfsm_strsiz(&info, &len2, NFS_MAXPATHLEN) != 0)
+               goto nfsmout;
        pathlen = len2 + 1;
        pathcp = malloc(pathlen, M_TEMP, M_WAITOK);
        iv.iov_base = pathcp;
@@ -1722,9 +1978,12 @@ nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        io.uio_segflg = UIO_SYSSPACE;
        io.uio_rw = UIO_READ;
        io.uio_procp = NULL;
-       nfsm_mtouio(&io, len2);
+       if (nfsm_mtouio(&info, &io, len2) != 0)
+               goto nfsmout;
        if (!info.nmi_v3) {
-               nfsm_dissect(sp, struct nfsv2_sattr *, NFSX_V2SATTR);
+               sp = (struct nfsv2_sattr *)nfsm_dissect(&info, NFSX_V2SATTR);
+               if (sp == NULL)
+                       goto nfsmout;
                va.va_mode = nfstov_mode(sp->sa_mode);
        }
        *(pathcp + len2) = '\0';
@@ -1773,11 +2032,12 @@ out:
                diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp);
                vrele(dirp);
        }
-       nfsm_reply(NFSX_SRVFH(info.nmi_v3) + NFSX_POSTOPATTR(info.nmi_v3)
-           + NFSX_WCCDATA(info.nmi_v3));
+       if (nfsm_reply(&info, nfsd, slp, mrq, error, NFSX_SRVFH(info.nmi_v3) +
+           NFSX_POSTOPATTR(info.nmi_v3) + NFSX_WCCDATA(info.nmi_v3)) != 0)
+               return 0;
        if (info.nmi_v3) {
                if (!error) {
-                       nfsm_srvpostop_fh(fhp);
+                       nfsm_srvpostop_fh(&info, fhp);
                        nfsm_srvpostop_attr(nfsd, 0, &va, &info);
                }
                nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
@@ -1817,9 +2077,7 @@ nfsrv_mkdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        struct nameidata nd;
        struct nfsm_info        info;
        u_int32_t *tl;
-       int32_t t1;
        int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
-       char *cp2;
        struct vnode *vp, *dirp = NULL;
        nfsfh_t nfh;
        fhandle_t *fhp;
@@ -1829,10 +2087,21 @@ nfsrv_mkdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        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)
+               return 0;
+       else if (error != 0)
+               goto nfsmout;
        fhp = &nfh.fh_generic;
-       nfsm_srvmtofh(fhp);
-       nfsm_srvnamesiz(len);
+       if (nfsm_srvmtofh2(&info, fhp) != 0)
+               goto nfsmout;
+       if (nfsm_srvnamesiz(&info, &len) != 0)
+               goto nfsmout;
+       if (error) {
+               if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0)
+                       return 0;
+       }
 
        NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, NULL, procp);
        nd.ni_cnd.cn_cred = cred;
@@ -1847,7 +2116,9 @@ nfsrv_mkdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
                }
        }
        if (error) {
-               nfsm_reply(NFSX_WCCDATA(info.nmi_v3));
+               if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                   NFSX_WCCDATA(info.nmi_v3)) != 0)
+                       return 0;
                nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
                    &info);
                if (dirp)
@@ -1862,7 +2133,9 @@ nfsrv_mkdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
                if (error)
                        goto nfsmout;
        } else {
-               nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
+               tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+               if (tl == NULL)
+                       goto nfsmout;
                va.va_mode = nfstov_mode(*tl++);
        }
        va.va_type = VDIR;
@@ -1892,11 +2165,12 @@ out:
                diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp);
                vrele(dirp);
        }
-       nfsm_reply(NFSX_SRVFH(info.nmi_v3) + NFSX_POSTOPATTR(info.nmi_v3) +
-           NFSX_WCCDATA(info.nmi_v3));
+       if (nfsm_reply(&info, nfsd, slp, mrq, error, NFSX_SRVFH(info.nmi_v3) +
+           NFSX_POSTOPATTR(info.nmi_v3) + NFSX_WCCDATA(info.nmi_v3)) != 0)
+               return 0;
        if (info.nmi_v3) {
                if (!error) {
-                       nfsm_srvpostop_fh(fhp);
+                       nfsm_srvpostop_fh(&info, fhp);
                        nfsm_srvpostop_attr(nfsd, 0, &va, &info);
                }
                nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
@@ -1930,10 +2204,7 @@ nfsrv_rmdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        struct mbuf *nam = nfsd->nd_nam;
        struct ucred *cred = &nfsd->nd_cr;
        struct nfsm_info        info;
-       u_int32_t *tl;
-       int32_t t1;
        int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
-       char *cp2;
        struct vnode *vp, *dirp = NULL;
        struct vattr dirfor, diraft;
        nfsfh_t nfh;
@@ -1945,10 +2216,21 @@ nfsrv_rmdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        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)
+               return 0;
+       else if (error != 0)
+               goto nfsmout;
        fhp = &nfh.fh_generic;
-       nfsm_srvmtofh(fhp);
-       nfsm_srvnamesiz(len);
+       if (nfsm_srvmtofh2(&info, fhp) != 0)
+               goto nfsmout;
+       if (nfsm_srvnamesiz(&info, &len) != 0)
+               goto nfsmout;
+       if (error) {
+               if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0)
+                       return 0;
+       }
 
        NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_SYSSPACE, NULL, procp);
        nd.ni_cnd.cn_cred = cred;
@@ -1964,7 +2246,9 @@ nfsrv_rmdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
                }
        }
        if (error) {
-               nfsm_reply(NFSX_WCCDATA(info.nmi_v3));
+               if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                   NFSX_WCCDATA(info.nmi_v3)) != 0)
+                       return 0;
                nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
                    &info);
                if (dirp)
@@ -2010,7 +2294,9 @@ out:
                diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp);
                vrele(dirp);
        }
-       nfsm_reply(NFSX_WCCDATA(info.nmi_v3));
+       if (nfsm_reply(&info, nfsd, slp, mrq, error,
+           NFSX_WCCDATA(info.nmi_v3)) != 0)
+               return 0;
        if (info.nmi_v3) {
                nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft,
                    &info);
@@ -2065,8 +2351,7 @@ nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        struct dirent *dp;
        struct nfsm_info        info;
        u_int32_t *tl;
-       int32_t t1;
-       char *cpos, *cend, *cp2, *rbuf;
+       char *cpos, *cend, *rbuf;
        struct vnode *vp;
        struct vattr at;
        nfsfh_t nfh;
@@ -2082,17 +2367,27 @@ nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        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)
+               return 0;
+       else if (error != 0)
+               goto nfsmout;
        fhp = &nfh.fh_generic;
-       nfsm_srvmtofh(fhp);
+       if (nfsm_srvmtofh2(&info, fhp) != 0)
+               goto nfsmout;
        if (info.nmi_v3) {
-               nfsm_dissect(tl, u_int32_t *, 5 * NFSX_UNSIGNED);
+               tl = (uint32_t *)nfsm_dissect(&info, 5 * NFSX_UNSIGNED);
+               if (tl == NULL)
+                       goto nfsmout;
                toff = fxdr_hyper(tl);
                tl += 2;
                verf = fxdr_hyper(tl);
                tl += 2;
        } else {
-               nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
+               tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED);
+               if (tl == NULL)
+                       goto nfsmout;
                toff = fxdr_unsigned(u_quad_t, *tl++);
        }
        off = toff;
@@ -2106,7 +2401,9 @@ nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        fullsiz = siz;
        error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
        if (error) {
-               nfsm_reply(NFSX_UNSIGNED);
+               if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                   NFSX_UNSIGNED) != 0)
+                       return 0;
                nfsm_srvpostop_attr(nfsd, getret, &at, &info);
                error = 0;
                goto nfsmout;
@@ -2117,7 +2414,9 @@ nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
                error = nfsrv_access(vp, VEXEC, cred, rdonly, procp, 0);
        if (error) {
                vput(vp);
-               nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3));
+               if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                   NFSX_POSTOPATTR(info.nmi_v3)) != 0)
+                       return 0;
                nfsm_srvpostop_attr(nfsd, getret, &at, &info);
                error = 0;
                goto nfsmout;
@@ -2150,7 +2449,9 @@ again:
        if (error) {
                vrele(vp);
                free(rbuf, M_TEMP, fullsiz);
-               nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3));
+               if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                   NFSX_POSTOPATTR(info.nmi_v3)) != 0)
+                       return 0;
                nfsm_srvpostop_attr(nfsd, getret, &at, &info);
                error = 0;
                goto nfsmout;
@@ -2164,8 +2465,11 @@ again:
                 */
                if (siz == 0) {
                        vrele(vp);
-                       nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3) + NFSX_COOKIEVERF(info.nmi_v3) +
-                               2 * NFSX_UNSIGNED);
+                       if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                           NFSX_POSTOPATTR(info.nmi_v3) +
+                           NFSX_COOKIEVERF(info.nmi_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);
@@ -2200,7 +2504,10 @@ again:
        }
 
        len = 3 * NFSX_UNSIGNED;        /* paranoia, probably can be 0 */
-       nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3) + NFSX_COOKIEVERF(info.nmi_v3) + siz);
+       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);
@@ -2230,10 +2537,10 @@ again:
                                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);
-       
+
                        /* Finish off the record */
                        if (info.nmi_v3) {
                                tl = nfsm_build(&info.nmi_mb, 2*NFSX_UNSIGNED);
@@ -2267,8 +2574,7 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        struct dirent *dp;
        struct nfsm_info        info;
        u_int32_t *tl;
-       int32_t t1;
-       char *cpos, *cend, *cp2, *rbuf;
+       char *cpos, *cend, *rbuf;
        struct vnode *vp, *nvp;
        struct flrep fl;
        nfsfh_t nfh;
@@ -2286,10 +2592,18 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        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)
+               return 0;
+       else if (error != 0)
+               goto nfsmout;
        fhp = &nfh.fh_generic;
-       nfsm_srvmtofh(fhp);
-       nfsm_dissect(tl, u_int32_t *, 6 * NFSX_UNSIGNED);
+       if (nfsm_srvmtofh2(&info, fhp) != 0)
+               goto nfsmout;
+       tl = (uint32_t *)nfsm_dissect(&info, 6 * NFSX_UNSIGNED);
+       if (tl == NULL)
+               goto nfsmout;
        off = toff = fxdr_hyper(tl);
        tl += 2;
        verf = fxdr_hyper(tl);
@@ -2305,7 +2619,9 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        fullsiz = siz;
        error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
        if (error) {
-               nfsm_reply(NFSX_UNSIGNED);
+               if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                   NFSX_UNSIGNED) != 0)
+                       return 0;
                nfsm_srvpostop_attr(nfsd, getret, &at, &info);
                error = 0;
                goto nfsmout;
@@ -2315,7 +2631,9 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
                error = nfsrv_access(vp, VEXEC, cred, rdonly, procp, 0);
        if (error) {
                vput(vp);
-               nfsm_reply(NFSX_V3POSTOPATTR);
+               if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                   NFSX_V3POSTOPATTR) != 0)
+                       return 0;
                nfsm_srvpostop_attr(nfsd, getret, &at, &info);
                error = 0;
                goto nfsmout;
@@ -2348,7 +2666,9 @@ again:
        if (error) {
                vrele(vp);
                free(rbuf, M_TEMP, fullsiz);
-               nfsm_reply(NFSX_V3POSTOPATTR);
+               if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                   NFSX_V3POSTOPATTR) != 0)
+                       return 0;
                nfsm_srvpostop_attr(nfsd, getret, &at, &info);
                error = 0;
                goto nfsmout;
@@ -2362,8 +2682,10 @@ again:
                 */
                if (siz == 0) {
                        vrele(vp);
-                       nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3COOKIEVERF +
-                               2 * NFSX_UNSIGNED);
+                       if (nfsm_reply(&info, nfsd, slp, mrq, 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);
                        txdr_hyper(at.va_filerev, tl);
@@ -2405,9 +2727,10 @@ again:
         *     entryplus3  *entries;
         *     bool eof;
         *  }
-        */     
+        */
        dirlen = len = NFSX_V3POSTOPATTR + NFSX_V3COOKIEVERF + 2 * NFSX_UNSIGNED;
-       nfsm_reply(cnt);
+       if (nfsm_reply(&info, nfsd, slp, mrq, error, cnt) != 0)
+               return 0;
        nfsm_srvpostop_attr(nfsd, getret, &at, &info);
        tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED);
        txdr_hyper(at.va_filerev, tl);
@@ -2515,20 +2838,26 @@ nfsrv_commit(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        nfsfh_t nfh;
        fhandle_t *fhp;
        u_int32_t *tl;
-       int32_t t1;
        int error = 0, rdonly, for_ret = 1, aft_ret = 1, cnt;
-       char *cp2;
        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)
+               return 0;
+       else if (error != 0)
+               goto nfsmout;
        fhp = &nfh.fh_generic;
-       nfsm_srvmtofh(fhp);
-       nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
+       if (nfsm_srvmtofh2(&info, fhp) != 0)
+               goto nfsmout;
+       tl = (uint32_t *)nfsm_dissect(&info, 3 * NFSX_UNSIGNED);
+       if (tl == NULL)
+               goto nfsmout;
 
        /*
         * XXX At this time VOP_FSYNC() does not accept offset and byte
@@ -2541,7 +2870,9 @@ nfsrv_commit(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
                cnt = 0;
        error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
        if (error) {
-               nfsm_reply(2 * NFSX_UNSIGNED);
+               if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                   2 * NFSX_UNSIGNED) != 0)
+                       return 0;
                nfsm_srvwcc(nfsd, for_ret, &bfor, aft_ret, &aft, &info);
                error = 0;
                goto nfsmout;
@@ -2550,7 +2881,9 @@ nfsrv_commit(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        error = VOP_FSYNC(vp, cred, MNT_WAIT, procp);
        aft_ret = VOP_GETATTR(vp, &aft, cred, procp);
        vput(vp);
-       nfsm_reply(NFSX_V3WCCDATA + NFSX_V3WRITEVERF);
+       if (nfsm_reply(&info, nfsd, slp, mrq, error,
+           NFSX_V3WCCDATA + NFSX_V3WRITEVERF) != 0)
+               return 0;
        nfsm_srvwcc(nfsd, for_ret, &bfor, aft_ret, &aft, &info);
        if (!error) {
                tl = nfsm_build(&info.nmi_mb, NFSX_V3WRITEVERF);
@@ -2575,10 +2908,7 @@ nfsrv_statfs(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        struct statfs *sf;
        struct nfs_statfs *sfp;
        struct nfsm_info        info;
-       u_int32_t *tl;
-       int32_t t1;
        int error = 0, rdonly, getret = 1;
-       char *cp2;
        struct vnode *vp;
        struct vattr at;
        nfsfh_t nfh;
@@ -2591,12 +2921,20 @@ nfsrv_statfs(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        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)
+               return 0;
+       else if (error != 0)
+               goto nfsmout;
        fhp = &nfh.fh_generic;
-       nfsm_srvmtofh(fhp);
+       if (nfsm_srvmtofh2(&info, fhp) != 0)
+               goto nfsmout;
        error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
        if (error) {
-               nfsm_reply(NFSX_UNSIGNED);
+               if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                   NFSX_UNSIGNED) != 0)
+                       return 0;
                nfsm_srvpostop_attr(nfsd, getret, &at, &info);
                error = 0;
                goto nfsmout;
@@ -2605,7 +2943,9 @@ nfsrv_statfs(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        error = VFS_STATFS(vp->v_mount, sf, procp);
        getret = VOP_GETATTR(vp, &at, cred, procp);
        vput(vp);
-       nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3) + NFSX_STATFS(info.nmi_v3));
+       if (nfsm_reply(&info, nfsd, slp, mrq, error,
+           NFSX_POSTOPATTR(info.nmi_v3) + NFSX_STATFS(info.nmi_v3)) != 0)
+               return 0;
        if (info.nmi_v3)
                nfsm_srvpostop_attr(nfsd, getret, &at, &info);
        if (error) {
@@ -2650,11 +2990,8 @@ nfsrv_fsinfo(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        struct mbuf *nam = nfsd->nd_nam;
        struct ucred *cred = &nfsd->nd_cr;
        struct nfsm_info        info;
-       u_int32_t *tl;
        struct nfsv3_fsinfo *sip;
-       int32_t t1;
        int error = 0, rdonly, getret = 1, pref;
-       char *cp2;
        struct vnode *vp;
        struct vattr at;
        nfsfh_t nfh;
@@ -2665,19 +3002,29 @@ nfsrv_fsinfo(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        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)
+               return 0;
+       else if (error != 0)
+               goto nfsmout;
        fhp = &nfh.fh_generic;
-       nfsm_srvmtofh(fhp);
+       if (nfsm_srvmtofh2(&info, fhp) != 0)
+               goto nfsmout;
        error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
        if (error) {
-               nfsm_reply(NFSX_UNSIGNED);
+               if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                   NFSX_UNSIGNED) != 0)
+                       return 0;
                nfsm_srvpostop_attr(nfsd, getret, &at, &info);
                error = 0;
                goto nfsmout;
        }
        getret = VOP_GETATTR(vp, &at, cred, procp);
        vput(vp);
-       nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3FSINFO);
+       if (nfsm_reply(&info, nfsd, slp, mrq, error,
+           NFSX_V3POSTOPATTR + NFSX_V3FSINFO) != 0)
+               return 0;
        nfsm_srvpostop_attr(nfsd, getret, &at, &info);
        sip = nfsm_build(&info.nmi_mb, NFSX_V3FSINFO);
 
@@ -2718,12 +3065,9 @@ nfsrv_pathconf(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        struct mbuf *nam = nfsd->nd_nam;
        struct ucred *cred = &nfsd->nd_cr;
        struct nfsm_info        info;
-       u_int32_t *tl;
        struct nfsv3_pathconf *pc;
-       int32_t t1;
        int error = 0, rdonly, getret = 1;
        register_t linkmax, namemax, chownres, notrunc;
-       char *cp2;
        struct vnode *vp;
        struct vattr at;
        nfsfh_t nfh;
@@ -2734,12 +3078,20 @@ nfsrv_pathconf(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        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)
+               return 0;
+       else if (error != 0)
+               goto nfsmout;
        fhp = &nfh.fh_generic;
-       nfsm_srvmtofh(fhp);
+       if (nfsm_srvmtofh2(&info, fhp) != 0)
+               goto nfsmout;
        error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly);
        if (error) {
-               nfsm_reply(NFSX_UNSIGNED);
+               if (nfsm_reply(&info, nfsd, slp, mrq, error,
+                   NFSX_UNSIGNED) != 0)
+                       return 0;
                nfsm_srvpostop_attr(nfsd, getret, &at, &info);
                error = 0;
                goto nfsmout;
@@ -2753,7 +3105,9 @@ nfsrv_pathconf(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
                error = VOP_PATHCONF(vp, _PC_NO_TRUNC, &notrunc);
        getret = VOP_GETATTR(vp, &at, cred, procp);
        vput(vp);
-       nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3PATHCONF);
+       if (nfsm_reply(&info, nfsd, slp, mrq, error,
+           NFSX_V3POSTOPATTR + NFSX_V3PATHCONF) != 0)
+               return 0;
        nfsm_srvpostop_attr(nfsd, getret, &at, &info);
        if (error) {
                error = 0;
@@ -2792,8 +3146,10 @@ nfsrv_null(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        info.nmi_md = nfsd->nd_md;
        info.nmi_dpos = nfsd->nd_dpos;
        info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3);
+       info.nmi_errorp = &error;
 
-       nfsm_reply(0);
+       if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0)
+               return 0;
        return (0);
 }
 
@@ -2803,7 +3159,7 @@ nfsrv_null(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
 int
 nfsrv_noop(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
     struct proc *procp, struct mbuf **mrq)
-{      
+{
        struct nfsm_info        info;
        int error;
 
@@ -2812,12 +3168,14 @@ nfsrv_noop(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        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;
-       nfsm_reply(0);
+       if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0)
+               return 0;
        return (0);
 }
 
index 1f8635e..7d695f8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: nfs_socket.c,v 1.148 2024/04/19 06:50:37 ratchov Exp $        */
+/*     $OpenBSD: nfs_socket.c,v 1.149 2024/04/30 17:04:23 miod Exp $   */
 /*     $NetBSD: nfs_socket.c,v 1.27 1996/04/15 20:20:00 thorpej Exp $  */
 
 /*
@@ -63,9 +63,9 @@
 #include <nfs/nfsproto.h>
 #include <nfs/nfs.h>
 #include <nfs/xdr_subs.h>
-#include <nfs/nfsm_subs.h>
 #include <nfs/nfsmount.h>
 #include <nfs/nfs_var.h>
+#include <nfs/nfsm_subs.h>
 
 /* External data, mostly RPC constants in XDR form. */
 extern u_int32_t rpc_reply, rpc_msgdenied, rpc_mismatch, rpc_vers,
@@ -158,7 +158,7 @@ nfs_init_rtt(struct nfsmount *nmp)
  * 
  * Use a gain of 0.125 on the mean and a gain of 0.25 on the deviation.
  *
- * NB: Since the timer resolution of NFS_HZ is so course, it can often
+ * NB: Since the timer resolution of NFS_HZ is so coarse, it can often
  * result in r_rtt == 0. Since r_rtt == N means that the actual RTT is
  * between N + dt and N + 2 - dt ticks, add 1 before calculating the
  * update values.
@@ -746,8 +746,7 @@ nfs_reply(struct nfsreq *myrep)
        struct nfsmount *nmp = myrep->r_nmp;
        struct nfsm_info        info;
        struct mbuf *nam;
-       u_int32_t rxid, *tl, t1;
-       caddr_t cp2;
+       u_int32_t rxid, *tl;
        int error;
 
        /*
@@ -788,7 +787,10 @@ nfs_reply(struct nfsreq *myrep)
                 */
                info.nmi_md = info.nmi_mrep;
                info.nmi_dpos = mtod(info.nmi_md, caddr_t);
-               nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
+               info.nmi_errorp = &error;
+               tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED);
+               if (tl == NULL)
+                       goto nfsmout;
                rxid = *tl++;
                if (*tl != rpc_reply) {
                        nfsstats.rpcinvalid++;
@@ -861,8 +863,7 @@ nfs_request(struct vnode *vp, int procnum, struct nfsm_info *infop)
        struct mbuf *m;
        u_int32_t *tl;
        struct nfsmount *nmp;
-       caddr_t cp2;
-       int t1, i, error = 0;
+       int i, error = 0;
        int trylater_delay;
        struct nfsreq *rep;
        struct nfsm_info info;
@@ -970,6 +971,7 @@ tryagain:
        info.nmi_mrep = rep->r_mrep;
        info.nmi_md = rep->r_md;
        info.nmi_dpos = rep->r_dpos;
+       info.nmi_errorp = &error;
        if (error) {
                infop->nmi_mrep = NULL;
                goto nfsmout1;
@@ -978,7 +980,9 @@ tryagain:
        /*
         * break down the rpc header and check if ok
         */
-       nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
+       tl = (uint32_t *)nfsm_dissect(&info, 3 * NFSX_UNSIGNED);
+       if (tl == NULL)
+               goto nfsmout;
        if (*tl++ == rpc_msgdenied) {
                if (*tl == rpc_mismatch)
                        error = EOPNOTSUPP;
@@ -995,13 +999,20 @@ tryagain:
         */
        tl++;                   /* Step over verifer type */
        i = fxdr_unsigned(int32_t, *tl);
-       if (i > 0)
-               nfsm_adv(nfsm_rndup(i));        /* Should not happen */
+       if (i > 0) {
+               /* Should not happen */
+               if (nfsm_adv(&info, nfsm_rndup(i)) != 0)
+                       goto nfsmout;
+       }
 
-       nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
+       tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+       if (tl == NULL)
+               goto nfsmout;
        /* 0 == ok */
        if (*tl == 0) {
-               nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
+               tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+               if (tl == NULL)
+                       goto nfsmout;
                if (*tl != 0) {
                        error = fxdr_unsigned(int, *tl);
                        if ((nmp->nm_flag & NFSMNT_NFSV3) &&
@@ -1434,8 +1445,6 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header)
 {
        int len, i;
        u_int32_t *tl;
-       int32_t t1;
-       caddr_t cp2;
        u_int32_t nfsvers, auth_type;
        int error = 0;
        struct nfsm_info info;
@@ -1443,15 +1452,21 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header)
        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) {
-               nfsm_dissect(tl, u_int32_t *, 10 * NFSX_UNSIGNED);
+               tl = (uint32_t *)nfsm_dissect(&info, 10 * NFSX_UNSIGNED);
+               if (tl == NULL)
+                       goto nfsmout;
                nd->nd_retxid = fxdr_unsigned(u_int32_t, *tl++);
                if (*tl++ != rpc_call) {
                        m_freem(info.nmi_mrep);
                        return (EBADRPC);
                }
-       } else
-               nfsm_dissect(tl, u_int32_t *, 8 * NFSX_UNSIGNED);
+       } else {
+               tl = (uint32_t *)nfsm_dissect(&info, 8 * NFSX_UNSIGNED);
+               if (tl == NULL)
+                       goto nfsmout;
+       }
        nd->nd_repstat = 0;
        nd->nd_flag = 0;
        if (*tl++ != rpc_vers) {
@@ -1499,8 +1514,11 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header)
                        m_freem(info.nmi_mrep);
                        return (EBADRPC);
                }
-               nfsm_adv(nfsm_rndup(len));
-               nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
+               if (nfsm_adv(&info, nfsm_rndup(len)) != 0)
+                       goto nfsmout;
+               tl = (uint32_t *)nfsm_dissect(&info, 3 * NFSX_UNSIGNED);
+               if (tl == NULL)
+                       goto nfsmout;
                memset(&nd->nd_cr, 0, sizeof (struct ucred));
                refcnt_init(&nd->nd_cr.cr_refcnt);
                nd->nd_cr.cr_uid = fxdr_unsigned(uid_t, *tl++);
@@ -1510,7 +1528,10 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header)
                        m_freem(info.nmi_mrep);
                        return (EBADRPC);
                }
-               nfsm_dissect(tl, u_int32_t *, (len + 2) * NFSX_UNSIGNED);
+               tl = (uint32_t *)
+                   nfsm_dissect(&info, (len + 2) * NFSX_UNSIGNED);
+               if (tl == NULL)
+                       goto nfsmout;
                for (i = 0; i < len; i++) {
                        if (i < NGROUPS_MAX)
                                nd->nd_cr.cr_groups[i] =
@@ -1524,8 +1545,10 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header)
                        m_freem(info.nmi_mrep);
                        return (EBADRPC);
                }
-               if (len > 0)
-                       nfsm_adv(nfsm_rndup(len));
+               if (len > 0) {
+                       if (nfsm_adv(&info, nfsm_rndup(len)) != 0)
+                               goto nfsmout;
+               }
        } else {
                nd->nd_repstat = (NFSERR_AUTHERR | AUTH_REJECTCRED);
                nd->nd_procnum = NFSPROC_NOOP;
index 23fa84b..1ccebbf 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: nfs_subs.c,v 1.146 2022/01/12 20:17:08 mbuhl Exp $    */
+/*     $OpenBSD: nfs_subs.c,v 1.147 2024/04/30 17:04:23 miod Exp $     */
 /*     $NetBSD: nfs_subs.c,v 1.27.4.3 1996/07/08 20:34:24 jtc Exp $    */
 
 /*
@@ -37,9 +37,9 @@
 
 
 /*
- * These functions support the macros and help fiddle mbuf chains for
- * the nfs op functions. They do things like create the rpc header and
- * copy data between mbuf chains and uio lists.
+ * These functions support the nfsm_subs.h inline functions and help fiddle
+ * mbuf chains for the nfs op functions. They do things such as creating the
+ * rpc header and copying data between mbuf chains and uio lists.
  */
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -59,9 +59,9 @@
 #include <nfs/nfsnode.h>
 #include <nfs/nfs.h>
 #include <nfs/xdr_subs.h>
-#include <nfs/nfsm_subs.h>
 #include <nfs/nfsmount.h>
 #include <nfs/nfs_var.h>
+#include <nfs/nfsm_subs.h>
 
 #include <uvm/uvm_extern.h>
 
@@ -791,8 +791,7 @@ nfsm_strtombuf(struct mbuf **mp, void *str, size_t len)
 /*
  * Help break down an mbuf chain by setting the first siz bytes contiguous
  * pointed to by returned val.
- * This is used by the macros nfsm_dissect and nfsm_dissecton for tough
- * cases. (The macros use the vars. dpos and dpos2)
+ * This is used by nfsm_dissect for tough cases.
  */
 int
 nfsm_disct(struct mbuf **mdp, caddr_t *dposp, int siz, int left, caddr_t *cp2)
@@ -824,7 +823,7 @@ nfsm_disct(struct mbuf **mdp, caddr_t *dposp, int siz, int left, caddr_t *cp2)
                mp = mp2;
                *cp2 = p = mtod(mp, caddr_t);
                bcopy(*dposp, p, left);         /* Copy what was left */
-               siz2 = siz-left;
+               siz2 = siz - left;
                p += left;
                mp2 = mp->m_next;
                /* Loop around copying up the siz2 bytes */
@@ -939,8 +938,7 @@ nfs_loadattrcache(struct vnode **vpp, struct mbuf **mdp, caddr_t *dposp,
        struct nfs_fattr *fp;
        extern const struct vops nfs_specvops;
        struct nfsnode *np;
-       int32_t t1;
-       caddr_t cp2;
+       int32_t avail;
        int error = 0;
        int32_t rdev;
        struct mbuf *md;
@@ -953,11 +951,10 @@ nfs_loadattrcache(struct vnode **vpp, struct mbuf **mdp, caddr_t *dposp,
        gid_t gid;
 
        md = *mdp;
-       t1 = (mtod(md, caddr_t) + md->m_len) - *dposp;
-       error = nfsm_disct(mdp, dposp, NFSX_FATTR(v3), t1, &cp2);
+       avail = (mtod(md, caddr_t) + md->m_len) - *dposp;
+       error = nfsm_disct(mdp, dposp, NFSX_FATTR(v3), avail, (caddr_t *)&fp);
        if (error)
                return (error);
-       fp = (struct nfs_fattr *)cp2;
        if (v3) {
                vtyp = nfsv3tov_type(fp->fa_type);
                vmode = fxdr_unsigned(mode_t, fp->fa_mode);
@@ -1050,34 +1047,29 @@ nfs_loadattrcache(struct vnode **vpp, struct mbuf **mdp, caddr_t *dposp,
                     fxdr_unsigned(int32_t, fp->fa2_blocksize);
                break;
        }
+       vap->va_nlink = fxdr_unsigned(nlink_t, fp->fa_nlink);
+       vap->va_uid = fxdr_unsigned(uid_t, fp->fa_uid);
+       vap->va_gid = fxdr_unsigned(gid_t, fp->fa_gid);
        if (v3) {
-               vap->va_nlink = fxdr_unsigned(nlink_t, fp->fa_nlink);
-               vap->va_uid = fxdr_unsigned(uid_t, fp->fa_uid);
-               vap->va_gid = fxdr_unsigned(gid_t, fp->fa_gid);
                vap->va_size = fxdr_hyper(&fp->fa3_size);
                vap->va_bytes = fxdr_hyper(&fp->fa3_used);
                vap->va_fileid = fxdr_hyper(&fp->fa3_fileid);
                fxdr_nfsv3time(&fp->fa3_atime, &vap->va_atime);
                fxdr_nfsv3time(&fp->fa3_ctime, &vap->va_ctime);
-               vap->va_flags = 0;
-               vap->va_filerev = 0;
        } else {
-               vap->va_nlink = fxdr_unsigned(nlink_t, fp->fa_nlink);
-               vap->va_uid = fxdr_unsigned(uid_t, fp->fa_uid);
-               vap->va_gid = fxdr_unsigned(gid_t, fp->fa_gid);
                vap->va_size = fxdr_unsigned(u_int32_t, fp->fa2_size);
                vap->va_bytes =
                    (u_quad_t)fxdr_unsigned(int32_t, fp->fa2_blocks) *
                    NFS_FABLKSIZE;
                vap->va_fileid = fxdr_unsigned(int32_t, fp->fa2_fileid);
                fxdr_nfsv2time(&fp->fa2_atime, &vap->va_atime);
-               vap->va_flags = 0;
                vap->va_ctime.tv_sec = fxdr_unsigned(u_int32_t,
                    fp->fa2_ctime.nfsv2_sec);
                vap->va_ctime.tv_nsec = 0;
                vap->va_gen = fxdr_unsigned(u_int32_t,fp->fa2_ctime.nfsv2_usec);
-               vap->va_filerev = 0;
        }
+       vap->va_flags = 0;
+       vap->va_filerev = 0;
 
        if (vap->va_size != np->n_size) {
                if (vap->va_type == VREG) {
@@ -1116,8 +1108,7 @@ nfs_attrtimeo(struct nfsnode *np)
        if (vp->v_type == VDIR) {
                maxto = nmp->nm_acdirmax;
                minto = nmp->nm_acdirmin;
-       }
-       else {
+       } else {
                maxto = nmp->nm_acregmax;
                minto = nmp->nm_acregmin;
        }
@@ -1338,7 +1329,7 @@ nfsm_adj(struct mbuf *mp, int len, int nul)
 }
 
 /*
- * Make these functions instead of macros, so that the kernel text size
+ * Make these non-inline functions, so that the kernel text size
  * doesn't get too big...
  */
 void
@@ -1835,44 +1826,64 @@ nfsm_srvsattr(struct mbuf **mp, struct vattr *va, struct mbuf *mrep,
     caddr_t *dposp)
 {
        struct nfsm_info        info;
-       uint32_t *tl, t1;
-       caddr_t cp2;
        int error = 0;
+       uint32_t *tl;
 
        info.nmi_md = *mp;
        info.nmi_dpos = *dposp;
        info.nmi_mrep = mrep;
+       info.nmi_errorp = &error;
 
-       nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
+       tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+       if (tl == NULL)
+               return error;
        if (*tl == nfs_true) {
-               nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
+               tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+               if (tl == NULL)
+                       return error;
                va->va_mode = nfstov_mode(*tl);
        }
 
-       nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
+       tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+       if (tl == NULL)
+               return error;
        if (*tl == nfs_true) {
-               nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
+               tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+               if (tl == NULL)
+                       return error;
                va->va_uid = fxdr_unsigned(uid_t, *tl);
        }
 
-       nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
+       tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+       if (tl == NULL)
+               return error;
        if (*tl == nfs_true) {
-               nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
+               tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+               if (tl == NULL)
+                       return error;
                va->va_gid = fxdr_unsigned(gid_t, *tl);
        }
 
-       nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
+       tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+       if (tl == NULL)
+               return error;
        if (*tl == nfs_true) {
-               nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
+               tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED);
+               if (tl == NULL)
+                       return error;
                va->va_size = fxdr_hyper(tl);
        }
 
-       nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
+       tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+       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;
-               nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
+               tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED);
+               if (tl == NULL)
+                       return error;
                fxdr_nfsv3time(tl, &va->va_atime);
                break;
        case NFSV3SATTRTIME_TOSERVER:
@@ -1881,12 +1892,16 @@ nfsm_srvsattr(struct mbuf **mp, struct vattr *va, struct mbuf *mrep,
                break;
        };
 
-       nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
+       tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+       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;
-               nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
+               tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED);
+               if (tl == NULL)
+                       return error;
                fxdr_nfsv3time(tl, &va->va_mtime);
                break;
        case NFSV3SATTRTIME_TOSERVER:
@@ -1897,8 +1912,7 @@ nfsm_srvsattr(struct mbuf **mp, struct vattr *va, struct mbuf *mrep,
 
        *dposp = info.nmi_dpos;
        *mp = info.nmi_md;
-nfsmout:
-       return (error);
+       return 0;
 }
 
 void
index 4f0e3bf..962a94b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: nfs_var.h,v 1.63 2017/02/22 11:42:46 mpi Exp $        */
+/*     $OpenBSD: nfs_var.h,v 1.64 2024/04/30 17:04:23 miod Exp $       */
 /*     $NetBSD: nfs_var.h,v 1.3 1996/02/18 11:53:54 fvdl Exp $ */
 
 /*
@@ -152,7 +152,6 @@ int nfsm_mbuftouio(struct mbuf **, struct uio *, int, caddr_t *);
 void nfsm_uiotombuf(struct mbuf **, struct uio *, size_t);
 void nfsm_strtombuf(struct mbuf **, void *, size_t);
 void nfsm_buftombuf(struct mbuf **, void *, size_t);
-int nfsm_disct(struct mbuf **, caddr_t *, int, int, caddr_t *);
 int nfs_adv(struct mbuf **, caddr_t *, int, int);
 int nfsm_strtmbuf(struct mbuf **, char **, char *, long);
 int nfs_vfs_init(struct vfsconf *);
@@ -164,6 +163,7 @@ int nfs_namei(struct nameidata *, fhandle_t *, int, struct nfssvc_sock *,
                   struct mbuf *, struct mbuf **, caddr_t *, struct vnode **,
                   struct proc *);
 void nfsm_v3attrbuild(struct mbuf **, struct vattr *, int);
+int nfsm_disct(struct mbuf **, caddr_t *, int, int, caddr_t *);
 void nfsm_adj(struct mbuf *, int, int);
 void nfsm_srvwcc(struct nfsrv_descript *, int, struct vattr *, int,
                      struct vattr *, struct nfsm_info *);
index 384a367..0c01f71 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: nfs_vfsops.c,v 1.128 2023/03/08 04:43:09 guenther Exp $       */
+/*     $OpenBSD: nfs_vfsops.c,v 1.129 2024/04/30 17:04:23 miod Exp $   */
 /*     $NetBSD: nfs_vfsops.c,v 1.46.4.1 1996/05/25 22:40:35 fvdl Exp $ */
 
 /*
@@ -63,9 +63,9 @@
 #include <nfs/nfs.h>
 #include <nfs/nfsmount.h>
 #include <nfs/xdr_subs.h>
-#include <nfs/nfsm_subs.h>
 #include <nfs/nfsdiskless.h>
 #include <nfs/nfs_var.h>
+#include <nfs/nfsm_subs.h>
 
 extern struct nfsstats nfsstats;
 extern int nfs_ticks;
@@ -120,15 +120,13 @@ nfs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p)
        struct vnode *vp;
        struct nfs_statfs *sfp = NULL;
        struct nfsm_info        info;
-       u_int32_t *tl;
-       int32_t t1;
-       caddr_t cp2;
        struct nfsmount *nmp = VFSTONFS(mp);
        int error = 0, retattr;
        struct ucred *cred;
        u_quad_t tquad;
 
        info.nmi_v3 = (nmp->nm_flag & NFSMNT_NFSV3);
+       info.nmi_errorp = &error;
 
        error = nfs_root(mp, &vp);
        if (error)
@@ -144,14 +142,19 @@ nfs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p)
        info.nmi_procp = p;
        info.nmi_cred = cred;
        error = nfs_request(vp, NFSPROC_FSSTAT, &info);
-       if (info.nmi_v3)
-               nfsm_postop_attr(vp, retattr);
+       if (info.nmi_v3) {
+               if (nfsm_postop_attr(&info, &vp, &retattr) != 0)
+                       goto nfsmout;
+       }
        if (error) {
                m_freem(info.nmi_mrep);
                goto nfsmout;
        }
 
-       nfsm_dissect(sfp, struct nfs_statfs *, NFSX_STATFS(info.nmi_v3));
+       sfp = (struct nfs_statfs *)
+           nfsm_dissect(&info, NFSX_STATFS(info.nmi_v3));
+       if (sfp == NULL)
+               goto nfsmout;
        sbp->f_iosize = min(nmp->nm_rsize, nmp->nm_wsize);
        if (info.nmi_v3) {
                sbp->f_bsize = NFS_FABLKSIZE;
@@ -193,9 +196,7 @@ nfs_fsinfo(struct nfsmount *nmp, struct vnode *vp, struct ucred *cred,
 {
        struct nfsv3_fsinfo *fsp;
        struct nfsm_info        info;
-       int32_t t1;
-       u_int32_t *tl, pref, max;
-       caddr_t cp2;
+       u_int32_t pref, max;
        int error = 0, retattr;
 
        nfsstats.rpccnt[NFSPROC_FSINFO]++;
@@ -204,15 +205,19 @@ nfs_fsinfo(struct nfsmount *nmp, struct vnode *vp, struct ucred *cred,
 
        info.nmi_procp = p;
        info.nmi_cred = cred;
+       info.nmi_errorp = &error;
        error = nfs_request(vp, NFSPROC_FSINFO, &info);
 
-       nfsm_postop_attr(vp, retattr);
+       if (nfsm_postop_attr(&info, &vp, &retattr) != 0)
+               goto nfsmout;
        if (error) {
                m_freem(info.nmi_mrep);
                goto nfsmout;
        }
 
-       nfsm_dissect(fsp, struct nfsv3_fsinfo *, NFSX_V3FSINFO);
+       fsp = (struct nfsv3_fsinfo *)nfsm_dissect(&info, NFSX_V3FSINFO);
+       if (fsp == NULL)
+               goto nfsmout;
        pref = fxdr_unsigned(u_int32_t, fsp->fs_wtpref);
        if (pref < nmp->nm_wsize)
                nmp->nm_wsize = (pref + NFS_FABLKSIZE - 1) &
index 61847ab..6ade5bb 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: nfs_vnops.c,v 1.195 2024/04/13 23:44:11 jsg Exp $     */
+/*     $OpenBSD: nfs_vnops.c,v 1.196 2024/04/30 17:04:23 miod Exp $    */
 /*     $NetBSD: nfs_vnops.c,v 1.62.4.1 1996/07/08 20:26:52 jtc Exp $   */
 
 /*
@@ -69,8 +69,8 @@
 #include <nfs/nfsnode.h>
 #include <nfs/nfsmount.h>
 #include <nfs/xdr_subs.h>
-#include <nfs/nfsm_subs.h>
 #include <nfs/nfs_var.h>
+#include <nfs/nfsm_subs.h>
 
 #include <uvm/uvm_extern.h>
 
@@ -289,6 +289,7 @@ nfs_null(struct vnode *vp, struct ucred *cred, struct proc *procp)
        int                      error = 0;
 
        info.nmi_mb = info.nmi_mreq = nfsm_reqhead(0);
+       info.nmi_errorp = &error;
        error = nfs_request(vp, NFSPROC_NULL, &info);
        m_freem(info.nmi_mrep);
        return (error);
@@ -306,8 +307,6 @@ nfs_access(void *v)
        struct vop_access_args *ap = v;
        struct vnode *vp = ap->a_vp;
        u_int32_t *tl;
-       int32_t t1;
-       caddr_t cp2;
        int error = 0, attrflag;
        u_int32_t mode, rmode;
        int v3 = NFS_ISV3(vp);
@@ -381,15 +380,19 @@ nfs_access(void *v)
 
                info.nmi_procp = ap->a_p;
                info.nmi_cred = ap->a_cred;
+               info.nmi_errorp = &error;
                error = nfs_request(vp, NFSPROC_ACCESS, &info);
 
-               nfsm_postop_attr(vp, attrflag);
+               if (nfsm_postop_attr(&info, &vp, &attrflag) != 0)
+                       goto nfsmout;
                if (error) {
                        m_freem(info.nmi_mrep);
                        goto nfsmout;
                }
 
-               nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
+               tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+               if (tl == NULL)
+                       goto nfsmout;
                rmode = fxdr_unsigned(u_int32_t, *tl);
                /*
                 * The NFS V3 spec does not clarify whether or not
@@ -554,6 +557,22 @@ nfs_close(void *v)
        return (error);
 }
 
+static inline int
+nfsm_loadattr(struct nfsm_info *infop, struct vnode **vpp, struct vattr *vap)
+{
+       struct vnode *ttvp = *vpp;
+       int error;
+
+       error = nfs_loadattrcache(&ttvp, &infop->nmi_md, &infop->nmi_dpos, vap);
+       if (error != 0) {
+               m_freem(infop->nmi_mrep);
+               *infop->nmi_errorp = error;
+               return error;
+       }
+       *vpp = ttvp;
+       return 0;
+}
+
 /*
  * nfs getattr call from vfs.
  */
@@ -564,7 +583,6 @@ nfs_getattr(void *v)
        struct vnode *vp = ap->a_vp;
        struct nfsnode *np = VTONFS(vp);
        struct nfsm_info        info;
-       int32_t t1;
        int error = 0;
 
        info.nmi_v3 = NFS_ISV3(vp);
@@ -585,9 +603,12 @@ nfs_getattr(void *v)
        nfsm_fhtom(&info, vp, info.nmi_v3);
        info.nmi_procp = ap->a_p;
        info.nmi_cred = ap->a_cred;
+       info.nmi_errorp = &error;
        error = nfs_request(vp, NFSPROC_GETATTR, &info);
-       if (!error)
-               nfsm_loadattr(vp, ap->a_vap);
+       if (!error) {
+               if (nfsm_loadattr(&info, &vp, ap->a_vap) != 0)
+                       goto nfsmout;
+       }
        m_freem(info.nmi_mrep);
 nfsmout: 
        return (error);
@@ -678,6 +699,42 @@ nfs_setattr(void *v)
        return (error);
 }
 
+/* Used as *flagp for nfsm_wcc_data() below */
+#define NFSV3_WCCRATTR 0
+#define NFSV3_WCCCHK   1
+
+static inline int
+nfsm_wcc_data(struct nfsm_info *infop, struct vnode **vpp, int *flagp)
+{
+       struct timespec mtime;
+       int ttattrf, ttretf = 0;
+       uint32_t *tl;
+
+       if (infop->nmi_mrep == NULL)
+               return 0;
+
+       tl = (uint32_t *)nfsm_dissect(infop, NFSX_UNSIGNED);
+       if (tl == NULL)
+               return 1;
+       if (*tl == nfs_true) {
+               tl = (uint32_t *)nfsm_dissect(infop, 6 * NFSX_UNSIGNED);
+               if (tl == NULL)
+                       return 1;
+               fxdr_nfsv3time(tl + 2, &mtime);
+               if (*flagp != NFSV3_WCCRATTR) {
+                       ttretf =
+                           timespeccmp(&VTONFS(*vpp)->n_mtime, &mtime, !=);
+               }
+       }
+       if (nfsm_postop_attr(infop, vpp, &ttattrf) != 0)
+               return 1;
+       if (*flagp != NFSV3_WCCRATTR)
+               *flagp = ttretf;
+       else 
+               *flagp = ttattrf;
+       return 0;
+}
+
 /*
  * Do an nfs setattr rpc.
  */
@@ -687,8 +744,6 @@ nfs_setattrrpc(struct vnode *vp, struct vattr *vap, struct ucred *cred,
 {
        struct nfsv2_sattr *sp;
        struct nfsm_info        info;
-       int32_t t1;
-       caddr_t cp2;
        u_int32_t *tl;
        int error = 0, wccflag = NFSV3_WCCRATTR;
        int v3 = NFS_ISV3(vp);
@@ -698,6 +753,7 @@ nfs_setattrrpc(struct vnode *vp, struct vattr *vap, struct ucred *cred,
        nfsstats.rpccnt[NFSPROC_SETATTR]++;
        info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(v3) + NFSX_SATTR(v3));
        nfsm_fhtom(&info, vp, v3);
+       info.nmi_errorp = &error;
 
        if (info.nmi_v3) {
                nfsm_v3attrbuild(&info.nmi_mb, vap, 1);
@@ -726,16 +782,40 @@ nfs_setattrrpc(struct vnode *vp, struct vattr *vap, struct ucred *cred,
        info.nmi_cred = cred;
        error = nfs_request(vp, NFSPROC_SETATTR, &info);
 
-       if (info.nmi_v3)
-               nfsm_wcc_data(vp, wccflag);
-       else if (error == 0)
-               nfsm_loadattr(vp, NULL);
+       if (info.nmi_v3) {
+               if (nfsm_wcc_data(&info, &vp, &wccflag) != 0)
+                       goto nfsmout;
+       }
+       else if (error == 0) {
+               if (nfsm_loadattr(&info, &vp, NULL) != 0)
+                       goto nfsmout;
+       }
 
        m_freem(info.nmi_mrep);
 nfsmout: 
        return (error);
 }
 
+static inline nfsfh_t *
+nfsm_getfh(struct nfsm_info *infop, int *sizep, int v3)
+{
+       int size;
+       if (v3) {
+               uint32_t *tl = (uint32_t *)nfsm_dissect(infop, NFSX_UNSIGNED);
+               if (tl == NULL)
+                       return NULL;
+               size = fxdr_unsigned(int, *tl);
+               if (size <= 0 || size > NFSX_V3FHMAX) {
+                       m_freem(infop->nmi_mrep);
+                       *infop->nmi_errorp = EBADRPC;
+                       return NULL;
+               }
+       } else
+               size = NFSX_V2FH;
+       *sizep = size;
+       return (nfsfh_t *)nfsm_dissect(infop, nfsm_rndup(size));
+}
+
 /*
  * nfs lookup call, one step at a time...
  * First look in cache
@@ -751,16 +831,14 @@ nfs_lookup(void *v)
        struct nfsm_info        info;
        int flags;
        struct vnode *newvp;
-       u_int32_t *tl;
-       int32_t t1;
        struct nfsmount *nmp;
-       caddr_t cp2;
        long len;
        nfsfh_t *fhp;
        struct nfsnode *np;
        int lockparent, wantparent, error = 0, attrflag, fhsize;
 
        info.nmi_v3 = NFS_ISV3(dvp);
+       info.nmi_errorp = &error;
 
        cnp->cn_flags &= ~PDIRUNLOCK;
        flags = cnp->cn_flags;
@@ -856,20 +934,24 @@ dorpc:
        info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3) +
            NFSX_UNSIGNED + nfsm_rndup(len));
        nfsm_fhtom(&info, dvp, info.nmi_v3);
-       nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN);
+       if (nfsm_strtom(&info, cnp->cn_nameptr, len, NFS_MAXNAMLEN) != 0)
+               goto nfsmout;
 
        info.nmi_procp = cnp->cn_proc;
        info.nmi_cred = cnp->cn_cred;
        error = nfs_request(dvp, NFSPROC_LOOKUP, &info);
 
        if (error) {
-               if (info.nmi_v3)
-                       nfsm_postop_attr(dvp, attrflag);
+               if (info.nmi_v3) {
+                       if (nfsm_postop_attr(&info, &dvp, &attrflag) != 0)
+                               goto nfsmout;
+               }
                m_freem(info.nmi_mrep);
                goto nfsmout;
        }
 
-       nfsm_getfh(fhp, fhsize, info.nmi_v3);
+       if ((fhp = nfsm_getfh(&info, &fhsize, info.nmi_v3)) == NULL)
+               goto nfsmout;
 
        /*
         * Handle RENAME case...
@@ -886,10 +968,14 @@ dorpc:
                }
                newvp = NFSTOV(np);
                if (info.nmi_v3) {
-                       nfsm_postop_attr(newvp, attrflag);
-                       nfsm_postop_attr(dvp, attrflag);
-               } else
-                       nfsm_loadattr(newvp, NULL);
+                       if (nfsm_postop_attr(&info, &newvp, &attrflag) != 0)
+                               goto nfsmout;
+                       if (nfsm_postop_attr(&info, &dvp, &attrflag) != 0)
+                               goto nfsmout;
+               } else {
+                       if (nfsm_loadattr(&info, &newvp, NULL) != 0)
+                               goto nfsmout;
+               }
                *vpp = newvp;
                m_freem(info.nmi_mrep);
                cnp->cn_flags |= SAVENAME;
@@ -910,10 +996,14 @@ dorpc:
                vref(dvp);
                newvp = dvp;
                if (info.nmi_v3) {
-                       nfsm_postop_attr(newvp, attrflag);
-                       nfsm_postop_attr(dvp, attrflag);
-               } else
-                       nfsm_loadattr(newvp, NULL);
+                       if (nfsm_postop_attr(&info, &newvp, &attrflag) != 0)
+                               goto nfsmout;
+                       if (nfsm_postop_attr(&info, &dvp, &attrflag) != 0)
+                               goto nfsmout;
+               } else {
+                       if (nfsm_loadattr(&info, &newvp, NULL) != 0)
+                               goto nfsmout;
+               }
        } else if (flags & ISDOTDOT) {
                VOP_UNLOCK(dvp);
                cnp->cn_flags |= PDIRUNLOCK;
@@ -928,10 +1018,14 @@ dorpc:
                newvp = NFSTOV(np);
 
                if (info.nmi_v3) {
-                       nfsm_postop_attr(newvp, attrflag);
-                       nfsm_postop_attr(dvp, attrflag);
-               } else
-                       nfsm_loadattr(newvp, NULL);
+                       if (nfsm_postop_attr(&info, &newvp, &attrflag) != 0)
+                               goto nfsmout;
+                       if (nfsm_postop_attr(&info, &dvp, &attrflag) != 0)
+                               goto nfsmout;
+               } else {
+                       if (nfsm_loadattr(&info, &newvp, NULL) != 0)
+                               goto nfsmout;
+               }
 
                if (lockparent && (flags & ISLASTCN)) {
                        if ((error = vn_lock(dvp, LK_EXCLUSIVE))) {
@@ -950,10 +1044,14 @@ dorpc:
                }
                newvp = NFSTOV(np);
                if (info.nmi_v3) {
-                       nfsm_postop_attr(newvp, attrflag);
-                       nfsm_postop_attr(dvp, attrflag);
-               } else
-                       nfsm_loadattr(newvp, NULL);
+                       if (nfsm_postop_attr(&info, &newvp, &attrflag) != 0)
+                               goto nfsmout;
+                       if (nfsm_postop_attr(&info, &dvp, &attrflag) != 0)
+                               goto nfsmout;
+               } else {
+                       if (nfsm_loadattr(&info, &newvp, NULL) != 0)
+                               goto nfsmout;
+               }
                if (!lockparent || !(flags & ISLASTCN)) {
                        VOP_UNLOCK(dvp);
                        cnp->cn_flags |= PDIRUNLOCK;
@@ -973,10 +1071,8 @@ dorpc:
 nfsmout: 
        if (error) {
                /*
-                * We get here only because of errors returned by
-                * the RPC. Otherwise we'll have returned above
-                * (the nfsm_* macros will jump to nfsmout
-                * on error).
+                * We get here only because of errors returned by the RPC.
+                * Otherwise we'd already have returned.
                 */
                if (error == ENOENT && (cnp->cn_flags & MAKEENTRY) &&
                    cnp->cn_nameiop != CREATE) {
@@ -1075,12 +1171,10 @@ int
 nfs_readlinkrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred)
 {
        struct nfsm_info        info;
-       u_int32_t *tl;
-       int32_t t1;
-       caddr_t cp2;
        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));
@@ -1090,11 +1184,15 @@ nfs_readlinkrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred)
        info.nmi_cred = cred;
        error = nfs_request(vp, NFSPROC_READLINK, &info);
 
-       if (info.nmi_v3)
-               nfsm_postop_attr(vp, attrflag);
+       if (info.nmi_v3) {
+               if (nfsm_postop_attr(&info, &vp, &attrflag) != 0)
+                       goto nfsmout;
+       }
        if (!error) {
-               nfsm_strsiz(len, NFS_MAXPATHLEN);
-               nfsm_mtouio(uiop, len);
+               if (nfsm_strsiz(&info, &len, NFS_MAXPATHLEN) != 0)
+                       goto nfsmout;
+               if (nfsm_mtouio(&info, uiop, len) != 0)
+                       goto nfsmout;
        }
 
        m_freem(info.nmi_mrep);
@@ -1112,12 +1210,11 @@ nfs_readrpc(struct vnode *vp, struct uio *uiop)
 {
        struct nfsm_info        info;
        u_int32_t *tl;
-       int32_t t1;
-       caddr_t cp2;
        struct nfsmount *nmp;
        int error = 0, len, retlen, tsiz, eof, attrflag;
 
        info.nmi_v3 = NFS_ISV3(vp);
+       info.nmi_errorp = &error;
 
        eof = 0;
 
@@ -1144,22 +1241,29 @@ nfs_readrpc(struct vnode *vp, struct uio *uiop)
                info.nmi_procp = curproc;
                info.nmi_cred = VTONFS(vp)->n_rcred;
                error = nfs_request(vp, NFSPROC_READ, &info);
-               if (info.nmi_v3)
-                       nfsm_postop_attr(vp, attrflag);
+               if (info.nmi_v3) {
+                       if (nfsm_postop_attr(&info, &vp, &attrflag) != 0)
+                               goto nfsmout;
+               }
                if (error) {
                        m_freem(info.nmi_mrep);
                        goto nfsmout;
                }
 
                if (info.nmi_v3) {
-                       nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
+                       tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED);
+                       if (tl == NULL)
+                               goto nfsmout;
                        eof = fxdr_unsigned(int, *(tl + 1));
                } else {
-                       nfsm_loadattr(vp, NULL);
+                       if (nfsm_loadattr(&info, &vp, NULL) != 0)
+                               goto nfsmout;
                }
 
-               nfsm_strsiz(retlen, nmp->nm_rsize);
-               nfsm_mtouio(uiop, retlen);
+               if (nfsm_strsiz(&info, &retlen, nmp->nm_rsize) != 0)
+                       goto nfsmout;
+               if (nfsm_mtouio(&info, uiop, retlen) != 0)
+                       goto nfsmout;
                m_freem(info.nmi_mrep);
                tsiz -= retlen;
                if (info.nmi_v3) {
@@ -1181,13 +1285,13 @@ nfs_writerpc(struct vnode *vp, struct uio *uiop, int *iomode, int *must_commit)
 {
        struct nfsm_info        info;
        u_int32_t *tl;
-       int32_t t1, backup;
-       caddr_t cp2;
+       int32_t backup;
        struct nfsmount *nmp = VFSTONFS(vp->v_mount);
        int error = 0, len, tsiz, wccflag = NFSV3_WCCRATTR, rlen, commit;
        int committed = NFSV3WRITE_FILESYNC;
 
        info.nmi_v3 = NFS_ISV3(vp);
+       info.nmi_errorp = &error;
 
 #ifdef DIAGNOSTIC
        if (uiop->uio_iovcnt != 1)
@@ -1230,7 +1334,8 @@ nfs_writerpc(struct vnode *vp, struct uio *uiop, int *iomode, int *must_commit)
                error = nfs_request(vp, NFSPROC_WRITE, &info);
                if (info.nmi_v3) {
                        wccflag = NFSV3_WCCCHK;
-                       nfsm_wcc_data(vp, wccflag);
+                       if (nfsm_wcc_data(&info, &vp, &wccflag) != 0)
+                               goto nfsmout;
                }
 
                if (error) {
@@ -1240,8 +1345,10 @@ nfs_writerpc(struct vnode *vp, struct uio *uiop, int *iomode, int *must_commit)
 
                if (info.nmi_v3) {
                        wccflag = NFSV3_WCCCHK;
-                       nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED
-                               + NFSX_V3WRITEVERF);
+                       tl = (uint32_t *)nfsm_dissect(&info,
+                           2 * NFSX_UNSIGNED + NFSX_V3WRITEVERF);
+                       if (tl == NULL)
+                               goto nfsmout;
                        rlen = fxdr_unsigned(int, *tl++);
                        if (rlen <= 0) {
                                error = NFSERR_IO;
@@ -1278,7 +1385,8 @@ nfs_writerpc(struct vnode *vp, struct uio *uiop, int *iomode, int *must_commit)
                                    NFSX_V3WRITEVERF);
                        }
                } else {
-                       nfsm_loadattr(vp, NULL);
+                       if (nfsm_loadattr(&info, &vp, NULL) != 0)
+                               goto nfsmout;
                }
                if (wccflag)
                    VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr.va_mtime;
@@ -1292,6 +1400,56 @@ nfsmout:
        return (error);
 }
 
+static inline int
+nfsm_mtofh(struct nfsm_info *infop, struct vnode *dvp, struct vnode **vpp,
+    int *flagp)
+{
+       struct nfsnode *ttnp;
+       nfsfh_t *ttfhp;
+       int ttfhsize;
+       uint32_t *tl;
+       int error;
+       int flag;
+
+       if (infop->nmi_v3) {
+               tl = (uint32_t *)nfsm_dissect(infop, NFSX_UNSIGNED);
+               if (tl == NULL)
+                       return 1;
+               flag = fxdr_unsigned(int, *tl);
+       } else
+               flag = 1;
+       if (flag) {
+               if ((ttfhp = nfsm_getfh(infop, &ttfhsize, infop->nmi_v3)) ==
+                   NULL) {
+                       return 1;
+               }
+               error = nfs_nget(dvp->v_mount, ttfhp, ttfhsize, &ttnp);
+               if (error != 0) {
+                       m_freem(infop->nmi_mrep);
+                       *infop->nmi_errorp = error;
+                       return error;
+               }
+               *vpp = NFSTOV(ttnp);
+       }
+       if (infop->nmi_v3) {
+               tl = (uint32_t *)nfsm_dissect(infop, NFSX_UNSIGNED);
+               if (tl == NULL)
+                       return 1;
+               if (flag)
+                       flag = fxdr_unsigned(int, *tl);
+               else if (fxdr_unsigned(int, *tl)) {
+                       if (nfsm_adv(infop, NFSX_V3FATTR) != 0)
+                               return 1;
+               }
+       }
+       if (flag) {
+               if (nfsm_loadattr(infop, vpp, NULL) != 0)
+                       return 1;
+       }
+       *flagp = flag;
+       return 0;
+}
+
 /*
  * nfs mknod rpc
  * For NFS v2 this is a kludge. Use a create rpc but with the IFMT bits of the
@@ -1304,14 +1462,13 @@ nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp,
        struct nfsv2_sattr *sp;
        struct nfsm_info        info;
        u_int32_t *tl;
-       int32_t t1;
        struct vnode *newvp = NULL;
        struct nfsnode *np = NULL;
-       char *cp2;
        int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0;
        u_int32_t rdev;
 
        info.nmi_v3 = NFS_ISV3(dvp);
+       info.nmi_errorp = &error;
 
        if (vap->va_type == VCHR || vap->va_type == VBLK)
                rdev = txdr_unsigned(vap->va_rdev);
@@ -1326,7 +1483,9 @@ nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp,
            4 * NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen) +
            NFSX_SATTR(info.nmi_v3));
        nfsm_fhtom(&info, dvp, info.nmi_v3);
-       nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
+       if (nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen,
+           NFS_MAXNAMLEN) != 0)
+               goto nfsmout;
 
        if (info.nmi_v3) {
                tl = nfsm_build(&info.nmi_mb, NFSX_UNSIGNED);
@@ -1352,7 +1511,8 @@ nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp,
        info.nmi_cred = cnp->cn_cred;
        error = nfs_request(dvp, NFSPROC_MKNOD, &info);
        if (!error) {
-               nfsm_mtofh(dvp, newvp, info.nmi_v3, gotvp);
+               if (nfsm_mtofh(&info, dvp, &newvp, &gotvp) != 0)
+                       goto nfsmout;
                if (!gotvp) {
                        error = nfs_lookitup(dvp, cnp->cn_nameptr,
                            cnp->cn_namelen, cnp->cn_cred, cnp->cn_proc, &np);
@@ -1360,8 +1520,10 @@ nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp,
                                newvp = NFSTOV(np);
                }
        }
-       if (info.nmi_v3)
-               nfsm_wcc_data(dvp, wccflag);
+       if (info.nmi_v3) {
+               if (nfsm_wcc_data(&info, &dvp, &wccflag) != 0)
+                       goto nfsmout;
+       }
        m_freem(info.nmi_mrep);
 
 nfsmout: 
@@ -1411,13 +1573,12 @@ nfs_create(void *v)
        struct nfsm_info        info;
        struct timespec ts;
        u_int32_t *tl;
-       int32_t t1;
        struct nfsnode *np = NULL;
        struct vnode *newvp = NULL;
-       caddr_t cp2;
        int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0, fmode = 0;
 
        info.nmi_v3 = NFS_ISV3(dvp);
+       info.nmi_errorp = &error;
 
        /*
         * Oops, not for me..
@@ -1434,7 +1595,9 @@ again:
            2 * NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen) +
            NFSX_SATTR(info.nmi_v3));
        nfsm_fhtom(&info, dvp, info.nmi_v3);
-       nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
+       if (nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen,
+           NFS_MAXNAMLEN) != 0)
+               goto nfsmout;
        if (info.nmi_v3) {
                tl = nfsm_build(&info.nmi_mb, NFSX_UNSIGNED);
                if (fmode & O_EXCL) {
@@ -1460,7 +1623,8 @@ again:
        info.nmi_cred = cnp->cn_cred;
        error = nfs_request(dvp, NFSPROC_CREATE, &info);
        if (!error) {
-               nfsm_mtofh(dvp, newvp, info.nmi_v3, gotvp);
+               if (nfsm_mtofh(&info, dvp, &newvp, &gotvp) != 0)
+                       goto nfsmout;
                if (!gotvp) {
                        error = nfs_lookitup(dvp, cnp->cn_nameptr,
                            cnp->cn_namelen, cnp->cn_cred, cnp->cn_proc, &np);
@@ -1468,8 +1632,10 @@ again:
                                newvp = NFSTOV(np);
                }
        }
-       if (info.nmi_v3)
-               nfsm_wcc_data(dvp, wccflag);
+       if (info.nmi_v3) {
+               if (nfsm_wcc_data(&info, &dvp, &wccflag) != 0)
+                       goto nfsmout;
+       }
        m_freem(info.nmi_mrep);
 
 nfsmout: 
@@ -1603,24 +1769,25 @@ nfs_removerpc(struct vnode *dvp, char *name, int namelen, struct ucred *cred,
     struct proc *proc)
 {
        struct nfsm_info        info;
-       u_int32_t *tl;
-       int32_t t1;
-       caddr_t cp2;
        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) +
             NFSX_UNSIGNED + nfsm_rndup(namelen));
        nfsm_fhtom(&info, dvp, info.nmi_v3);
-       nfsm_strtom(name, namelen, NFS_MAXNAMLEN);
+       if (nfsm_strtom(&info, name, namelen, NFS_MAXNAMLEN) != 0)
+               goto nfsmout;
 
        info.nmi_procp = proc;
        info.nmi_cred = cred;
        error = nfs_request(dvp, NFSPROC_REMOVE, &info);
-       if (info.nmi_v3)
-               nfsm_wcc_data(dvp, wccflag);
+       if (info.nmi_v3) {
+               if (nfsm_wcc_data(&info, &dvp, &wccflag) != 0)
+                       goto nfsmout;
+       }
        m_freem(info.nmi_mrep);
 
 nfsmout: 
@@ -1717,27 +1884,29 @@ nfs_renamerpc(struct vnode *fdvp, char *fnameptr, int fnamelen,
     struct proc *proc)
 {
        struct nfsm_info        info;
-       u_int32_t *tl;
-       int32_t t1;
-       caddr_t cp2;
        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) +
            NFSX_UNSIGNED) * 2 + nfsm_rndup(fnamelen) + nfsm_rndup(tnamelen));
        nfsm_fhtom(&info, fdvp, info.nmi_v3);
-       nfsm_strtom(fnameptr, fnamelen, NFS_MAXNAMLEN);
+       if (nfsm_strtom(&info, fnameptr, fnamelen, NFS_MAXNAMLEN) != 0)
+               goto nfsmout;
        nfsm_fhtom(&info, tdvp, info.nmi_v3);
-       nfsm_strtom(tnameptr, tnamelen, NFS_MAXNAMLEN);
+       if (nfsm_strtom(&info, tnameptr, tnamelen, NFS_MAXNAMLEN) != 0)
+               goto nfsmout;
 
        info.nmi_procp = proc;
        info.nmi_cred = cred;
        error = nfs_request(fdvp, NFSPROC_RENAME, &info);
        if (info.nmi_v3) {
-               nfsm_wcc_data(fdvp, fwccflag);
-               nfsm_wcc_data(tdvp, twccflag);
+               if (nfsm_wcc_data(&info, &fdvp, &fwccflag) != 0)
+                       goto nfsmout;
+               if (nfsm_wcc_data(&info, &tdvp, &twccflag) != 0)
+                       goto nfsmout;
        }
        m_freem(info.nmi_mrep);
 
@@ -1762,12 +1931,10 @@ nfs_link(void *v)
        struct vnode *dvp = ap->a_dvp;
        struct componentname *cnp = ap->a_cnp;
        struct nfsm_info        info;
-       u_int32_t *tl;
-       int32_t t1;
-       caddr_t cp2;
        int error = 0, wccflag = NFSV3_WCCRATTR, attrflag = 0;
 
        info.nmi_v3 = NFS_ISV3(vp);
+       info.nmi_errorp = &error;
 
        error = vn_lock(vp, LK_EXCLUSIVE);
        if (error != 0) {
@@ -1788,14 +1955,18 @@ nfs_link(void *v)
            NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen));
        nfsm_fhtom(&info, vp, info.nmi_v3);
        nfsm_fhtom(&info, dvp, info.nmi_v3);
-       nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
+       if (nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen,
+           NFS_MAXNAMLEN) != 0)
+               goto nfsmout;
 
        info.nmi_procp = cnp->cn_proc;
        info.nmi_cred = cnp->cn_cred;
        error = nfs_request(vp, NFSPROC_LINK, &info);
        if (info.nmi_v3) {
-               nfsm_postop_attr(vp, attrflag);
-               nfsm_wcc_data(dvp, wccflag);
+               if (nfsm_postop_attr(&info, &vp, &attrflag) != 0)
+                       goto nfsmout;
+               if (nfsm_wcc_data(&info, &dvp, &wccflag) != 0)
+                       goto nfsmout;
        }
        m_freem(info.nmi_mrep);
 nfsmout: 
@@ -1825,13 +1996,11 @@ nfs_symlink(void *v)
        struct componentname *cnp = ap->a_cnp;
        struct nfsv2_sattr *sp;
        struct nfsm_info        info;
-       u_int32_t *tl;
-       int32_t t1;
-       caddr_t cp2;
        int slen, error = 0, wccflag = NFSV3_WCCRATTR, gotvp;
        struct vnode *newvp = NULL;
 
        info.nmi_v3 = NFS_ISV3(dvp);
+       info.nmi_errorp = &error;
 
        nfsstats.rpccnt[NFSPROC_SYMLINK]++;
        slen = strlen(ap->a_target);
@@ -1839,10 +2008,13 @@ nfs_symlink(void *v)
            2 * NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen) + nfsm_rndup(slen) +
            NFSX_SATTR(info.nmi_v3));
        nfsm_fhtom(&info, dvp, info.nmi_v3);
-       nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
+       if (nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen,
+           NFS_MAXNAMLEN) != 0)
+               goto nfsmout;
        if (info.nmi_v3)
                nfsm_v3attrbuild(&info.nmi_mb, vap, 0);
-       nfsm_strtom(ap->a_target, slen, NFS_MAXPATHLEN);
+       if (nfsm_strtom(&info, ap->a_target, slen, NFS_MAXPATHLEN) != 0)
+               goto nfsmout;
        if (!info.nmi_v3) {
                sp = nfsm_build(&info.nmi_mb, NFSX_V2SATTR);
                sp->sa_mode = vtonfsv2_mode(VLNK, vap->va_mode);
@@ -1857,9 +2029,12 @@ nfs_symlink(void *v)
        info.nmi_cred = cnp->cn_cred;
        error = nfs_request(dvp, NFSPROC_SYMLINK, &info);
        if (info.nmi_v3) {
-               if (!error)
-                       nfsm_mtofh(dvp, newvp, info.nmi_v3, gotvp);
-               nfsm_wcc_data(dvp, wccflag);
+               if (!error) {
+                       if (nfsm_mtofh(&info, dvp, &newvp, &gotvp) != 0)
+                               goto nfsmout;
+               }
+               if (nfsm_wcc_data(&info, &dvp, &wccflag) != 0)
+                       goto nfsmout;
        }
        m_freem(info.nmi_mrep);
 
@@ -1887,23 +2062,22 @@ nfs_mkdir(void *v)
        struct componentname *cnp = ap->a_cnp;
        struct nfsv2_sattr *sp;
        struct nfsm_info        info;
-       u_int32_t *tl;
-       int32_t t1;
        int len;
        struct nfsnode *np = NULL;
        struct vnode *newvp = NULL;
-       caddr_t cp2;
        int error = 0, wccflag = NFSV3_WCCRATTR;
        int gotvp = 0;
 
        info.nmi_v3 = NFS_ISV3(dvp);
+       info.nmi_errorp = &error;
 
        len = cnp->cn_namelen;
        nfsstats.rpccnt[NFSPROC_MKDIR]++;
        info.nmi_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);
-       nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN);
+       if (nfsm_strtom(&info, cnp->cn_nameptr, len, NFS_MAXNAMLEN) != 0)
+               goto nfsmout;
 
        if (info.nmi_v3) {
                nfsm_v3attrbuild(&info.nmi_mb, vap, 0);
@@ -1920,10 +2094,14 @@ nfs_mkdir(void *v)
        info.nmi_procp = cnp->cn_proc;
        info.nmi_cred = cnp->cn_cred;
        error = nfs_request(dvp, NFSPROC_MKDIR, &info);
-       if (!error)
-               nfsm_mtofh(dvp, newvp, info.nmi_v3, gotvp);
-       if (info.nmi_v3)
-               nfsm_wcc_data(dvp, wccflag);
+       if (!error) {
+               if (nfsm_mtofh(&info, dvp, &newvp, &gotvp) != 0)
+                       goto nfsmout;
+       }
+       if (info.nmi_v3) {
+               if (nfsm_wcc_data(&info, &dvp, &wccflag) != 0)
+                       goto nfsmout;
+       }
        m_freem(info.nmi_mrep);
 
 nfsmout: 
@@ -1965,24 +2143,26 @@ nfs_rmdir(void *v)
        struct vnode *dvp = ap->a_dvp;
        struct componentname *cnp = ap->a_cnp;
        struct nfsm_info        info;
-       u_int32_t *tl;
-       int32_t t1;
-       caddr_t cp2;
        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) +
            NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen));
        nfsm_fhtom(&info, dvp, info.nmi_v3);
-       nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
+       if (nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen,
+           NFS_MAXNAMLEN) != 0)
+               goto nfsmout;
 
        info.nmi_procp = cnp->cn_proc;
        info.nmi_cred = cnp->cn_cred;
        error = nfs_request(dvp,  NFSPROC_RMDIR, &info);
-       if (info.nmi_v3)
-               nfsm_wcc_data(dvp, wccflag);
+       if (info.nmi_v3) {
+               if (nfsm_wcc_data(&info, &dvp, &wccflag) != 0)
+                       goto nfsmout;
+       }
        m_freem(info.nmi_mrep);
 
 nfsmout: 
@@ -2159,8 +2339,6 @@ nfs_readdirrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
        struct nfsm_info        info;
        u_int32_t *tl;
        caddr_t cp;
-       int32_t t1;
-       caddr_t cp2;
        nfsuint64 cookie;
        struct nfsmount *nmp = VFSTONFS(vp->v_mount);
        struct nfsnode *dnp = VTONFS(vp);
@@ -2169,6 +2347,7 @@ nfs_readdirrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
        int attrflag;
 
        info.nmi_v3 = NFS_ISV3(vp);
+       info.nmi_errorp = &error;
 
 #ifdef DIAGNOSTIC
        if (uiop->uio_iovcnt != 1 ||
@@ -2209,8 +2388,10 @@ nfs_readdirrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
                info.nmi_procp = uiop->uio_procp;
                info.nmi_cred = cred;
                error = nfs_request(vp, NFSPROC_READDIR, &info);
-               if (info.nmi_v3)
-                       nfsm_postop_attr(vp, attrflag);
+               if (info.nmi_v3) {
+                       if (nfsm_postop_attr(&info, &vp, &attrflag) != 0)
+                               goto nfsmout;
+               }
 
                if (error) {
                        m_freem(info.nmi_mrep);
@@ -2218,25 +2399,32 @@ nfs_readdirrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
                }
 
                if (info.nmi_v3) {
-                       nfsm_dissect(tl, u_int32_t *,
-                           2 * NFSX_UNSIGNED);
+                       tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED);
+                       if (tl == NULL)
+                               goto nfsmout;
                        dnp->n_cookieverf.nfsuquad[0] = *tl++;
                        dnp->n_cookieverf.nfsuquad[1] = *tl;
                }
 
-               nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
+               tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+               if (tl == NULL)
+                       goto nfsmout;
                more_dirs = fxdr_unsigned(int, *tl);
 
                /* loop thru the dir entries, doctoring them to dirent form */
                while (more_dirs && bigenough) {
                        if (info.nmi_v3) {
-                               nfsm_dissect(tl, u_int32_t *,
+                               tl = (uint32_t *)nfsm_dissect(&info,
                                    3 * NFSX_UNSIGNED);
+                               if (tl == NULL)
+                                       goto nfsmout;
                                fileno = fxdr_hyper(tl);
                                len = fxdr_unsigned(int, *(tl + 2));
                        } else {
-                               nfsm_dissect(tl, u_int32_t *,
+                               tl = (uint32_t *)nfsm_dissect(&info,
                                    2 * NFSX_UNSIGNED);
+                               if (tl == NULL)
+                                       goto nfsmout;
                                fileno = fxdr_unsigned(u_quad_t, *tl++);
                                len = fxdr_unsigned(int, *tl);
                        }
@@ -2272,22 +2460,27 @@ nfs_readdirrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
                                    (char *)uiop->uio_iov->iov_base +
                                    NFS_DIRHDSIZ;
                                uiop->uio_iov->iov_len -= NFS_DIRHDSIZ;
-                               nfsm_mtouio(uiop, len);
+                               if (nfsm_mtouio(&info, uiop, len) != 0)
+                                       goto nfsmout;
                                cp = uiop->uio_iov->iov_base;
                                tlen -= NFS_DIRHDSIZ + len;
                                *cp = '\0';     /* null terminate */
                                uiop->uio_iov->iov_base += tlen;
                                uiop->uio_iov->iov_len -= tlen;
                                uiop->uio_resid -= tlen;
-                       } else
-                               nfsm_adv(nfsm_rndup(len));
+                       } else {
+                               if (nfsm_adv(&info, nfsm_rndup(len)) != 0)
+                                       goto nfsmout;
+                       }
                        if (info.nmi_v3) {
-                               nfsm_dissect(tl, u_int32_t *,
+                               tl = (uint32_t *)nfsm_dissect(&info,
                                    3 * NFSX_UNSIGNED);
                        } else {
-                               nfsm_dissect(tl, u_int32_t *,
+                               tl = (uint32_t *)nfsm_dissect(&info,
                                    2 * NFSX_UNSIGNED);
                        }
+                       if (tl == NULL)
+                               goto nfsmout;
                        if (bigenough) {
                                if (info.nmi_v3) {
                                        ndp->cookie[0] = cookie.nfsuquad[0] =
@@ -2306,7 +2499,9 @@ nfs_readdirrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
                 * If at end of rpc data, get the eof boolean
                 */
                if (!more_dirs) {
-                       nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
+                       tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+                       if (tl == NULL)
+                               goto nfsmout;
                        more_dirs = (fxdr_unsigned(int, *tl) == 0);
                }
                m_freem(info.nmi_mrep);
@@ -2353,9 +2548,8 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
        struct nfsm_info        info;
        u_int32_t *tl;
        caddr_t cp;
-       int32_t t1;
        struct vnode *newvp;
-       caddr_t cp2, dpossav1, dpossav2;
+       caddr_t dpossav1, dpossav2;
        struct mbuf *mdsav1, *mdsav2;
        struct nameidata nami, *ndp = &nami;
        struct componentname *cnp = &ndp->ni_cnd;
@@ -2403,21 +2597,27 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
 
                info.nmi_procp = uiop->uio_procp;
                info.nmi_cred = cred;
+               info.nmi_errorp = &error;
                error = nfs_request(vp, NFSPROC_READDIRPLUS, &info);
-               nfsm_postop_attr(vp, attrflag);
+               if (nfsm_postop_attr(&info, &vp, &attrflag) != 0)
+                       goto nfsmout;
                if (error) {
                        m_freem(info.nmi_mrep);
                        goto nfsmout;
                }
 
-               nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
+               tl = (uint32_t *)nfsm_dissect(&info, 3 * NFSX_UNSIGNED);
+               if (tl == NULL)
+                       goto nfsmout;
                dnp->n_cookieverf.nfsuquad[0] = *tl++;
                dnp->n_cookieverf.nfsuquad[1] = *tl++;
                more_dirs = fxdr_unsigned(int, *tl);
 
                /* loop thru the dir entries, doctoring them to 4bsd form */
                while (more_dirs && bigenough) {
-                       nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
+                       tl = (uint32_t *)nfsm_dissect(&info, 3 * NFSX_UNSIGNED);
+                       if (tl == NULL)
+                               goto nfsmout;
                        fileno = fxdr_hyper(tl);
                        len = fxdr_unsigned(int, *(tl + 2));
                        if (len <= 0 || len > NFS_MAXNAMLEN) {
@@ -2455,16 +2655,21 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
                                uiop->uio_iov->iov_len -= NFS_DIRHDSIZ;
                                cnp->cn_nameptr = uiop->uio_iov->iov_base;
                                cnp->cn_namelen = len;
-                               nfsm_mtouio(uiop, len);
+                               if (nfsm_mtouio(&info, uiop, len) != 0)
+                                       goto nfsmout;
                                cp = uiop->uio_iov->iov_base;
                                tlen -= NFS_DIRHDSIZ + len;
                                *cp = '\0';
                                uiop->uio_iov->iov_base += tlen;
                                uiop->uio_iov->iov_len -= tlen;
                                uiop->uio_resid -= tlen;
-                       } else
-                               nfsm_adv(nfsm_rndup(len));
-                       nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
+                       } else {
+                               if (nfsm_adv(&info, nfsm_rndup(len)) != 0)
+                                       goto nfsmout;
+                       }
+                       tl = (uint32_t *)nfsm_dissect(&info, 3 * NFSX_UNSIGNED);
+                       if (tl == NULL)
+                               goto nfsmout;
                        if (bigenough) {
                                ndirp->cookie[0] = cookie.nfsuquad[0] = *tl++;
                                ndirp->cookie[1] = cookie.nfsuquad[1] = *tl++;
@@ -2480,11 +2685,18 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
                        if (attrflag) {
                                dpossav1 = info.nmi_dpos;
                                mdsav1 = info.nmi_md;
-                               nfsm_adv(NFSX_V3FATTR);
-                               nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
+                               if (nfsm_adv(&info, NFSX_V3FATTR) != 0)
+                                       goto nfsmout;
+                               tl = (uint32_t *)
+                                   nfsm_dissect(&info, NFSX_UNSIGNED);
+                               if (tl == NULL)
+                                       goto nfsmout;
                                doit = fxdr_unsigned(int, *tl);
                                if (doit) {
-                                       nfsm_getfh(fhp, fhsize, 1);
+                                       if ((fhp =
+                                           nfsm_getfh(&info, &fhsize, 1)) ==
+                                           NULL)
+                                               goto nfsmout;
                                        if (NFS_CMPFH(dnp, fhp, fhsize)) {
                                                vref(vp);
                                                newvp = vp;
@@ -2503,7 +2715,9 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
                                        info.nmi_dpos = dpossav1;
                                        mdsav2 = info.nmi_md;
                                        info.nmi_md = mdsav1;
-                                       nfsm_loadattr(newvp, NULL);
+                                       if (nfsm_loadattr(&info, &newvp,
+                                           NULL) != 0)
+                                               goto nfsmout;
                                        info.nmi_dpos = dpossav2;
                                        info.nmi_md = mdsav2;
                                        dp->d_type = IFTODT(
@@ -2518,10 +2732,15 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
                                }
                        } else {
                                /* Just skip over the file handle */
-                               nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
+                               tl = (uint32_t *)
+                                   nfsm_dissect(&info, NFSX_UNSIGNED);
+                               if (tl == NULL)
+                                       goto nfsmout;
                                i = fxdr_unsigned(int, *tl);
-                               if (i > 0)
-                                       nfsm_adv(nfsm_rndup(i));
+                               if (i > 0) {
+                                       if (nfsm_adv(&info, nfsm_rndup(i)) != 0)
+                                               goto nfsmout;
+                               }
                        }
                        if (newvp != NULLVP) {
                                if (newvp == vp)
@@ -2530,14 +2749,18 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
                                        vput(newvp);
                                newvp = NULLVP;
                        }
-                       nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
+                       tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+                       if (tl == NULL)
+                               goto nfsmout;
                        more_dirs = fxdr_unsigned(int, *tl);
                }
                /*
                 * If at end of rpc data, get the eof boolean
                 */
                if (!more_dirs) {
-                       nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
+                       tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED);
+                       if (tl == NULL)
+                               goto nfsmout;
                        more_dirs = (fxdr_unsigned(int, *tl) == 0);
                }
                m_freem(info.nmi_mrep);
@@ -2650,21 +2873,20 @@ nfs_lookitup(struct vnode *dvp, char *name, int len, struct ucred *cred,
     struct proc *procp, struct nfsnode **npp)
 {
        struct nfsm_info        info;
-       u_int32_t *tl;
-       int32_t t1;
        struct vnode *newvp = NULL;
        struct nfsnode *np, *dnp = VTONFS(dvp);
-       caddr_t cp2;
        int error = 0, fhlen, attrflag = 0;
        nfsfh_t *nfhp;
 
        info.nmi_v3 = NFS_ISV3(dvp);
+       info.nmi_errorp = &error;
 
        nfsstats.rpccnt[NFSPROC_LOOKUP]++;
        info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3) + NFSX_UNSIGNED +
            nfsm_rndup(len));
        nfsm_fhtom(&info, dvp, info.nmi_v3);
-       nfsm_strtom(name, len, NFS_MAXNAMLEN);
+       if (nfsm_strtom(&info, name, len, NFS_MAXNAMLEN) != 0)
+               goto nfsmout;
 
        info.nmi_procp = procp;
        info.nmi_cred = cred;
@@ -2675,7 +2897,8 @@ nfs_lookitup(struct vnode *dvp, char *name, int len, struct ucred *cred,
        }
 
        if (npp && !error) {
-               nfsm_getfh(nfhp, fhlen, info.nmi_v3);
+               if ((nfhp = nfsm_getfh(&info, &fhlen, info.nmi_v3)) == NULL)
+                       goto nfsmout;
                if (*npp) {
                        np = *npp;
                        np->n_fhp = &np->n_fh;
@@ -2695,7 +2918,8 @@ nfs_lookitup(struct vnode *dvp, char *name, int len, struct ucred *cred,
                        newvp = NFSTOV(np);
                }
                if (info.nmi_v3) {
-                       nfsm_postop_attr(newvp, attrflag);
+                       if (nfsm_postop_attr(&info, &newvp, &attrflag) != 0)
+                               goto nfsmout;
                        if (!attrflag && *npp == NULL) {
                                m_freem(info.nmi_mrep);
                                if (newvp == dvp)
@@ -2704,8 +2928,10 @@ nfs_lookitup(struct vnode *dvp, char *name, int len, struct ucred *cred,
                                        vput(newvp);
                                return (ENOENT);
                        }
-               } else
-                       nfsm_loadattr(newvp, NULL);
+               } else {
+                       if (nfsm_loadattr(&info, &newvp, NULL) != 0)
+                               goto nfsmout;
+               }
        }
        m_freem(info.nmi_mrep);
 nfsmout:
@@ -2729,9 +2955,7 @@ nfs_commit(struct vnode *vp, u_quad_t offset, int cnt, struct proc *procp)
 {
        struct nfsm_info        info;
        u_int32_t *tl;
-       int32_t t1;
        struct nfsmount *nmp = VFSTONFS(vp->v_mount);
-       caddr_t cp2;
        int error = 0, wccflag = NFSV3_WCCRATTR;
 
        if ((nmp->nm_flag & NFSMNT_HASWRITEVERF) == 0)
@@ -2739,6 +2963,7 @@ nfs_commit(struct vnode *vp, u_quad_t offset, int cnt, struct proc *procp)
        nfsstats.rpccnt[NFSPROC_COMMIT]++;
        info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(1));
        nfsm_fhtom(&info, vp, 1);
+       info.nmi_errorp = &error;
 
        tl = nfsm_build(&info.nmi_mb, 3 * NFSX_UNSIGNED);
        txdr_hyper(offset, tl);
@@ -2748,10 +2973,13 @@ nfs_commit(struct vnode *vp, u_quad_t offset, int cnt, struct proc *procp)
        info.nmi_procp = procp;
        info.nmi_cred = VTONFS(vp)->n_wcred;
        error = nfs_request(vp, NFSPROC_COMMIT, &info);
-       nfsm_wcc_data(vp, wccflag);
+       if (nfsm_wcc_data(&info, &vp, &wccflag) != 0)
+               goto nfsmout;
 
        if (!error) {
-               nfsm_dissect(tl, u_int32_t *, NFSX_V3WRITEVERF);
+               tl = (uint32_t *)nfsm_dissect(&info, NFSX_V3WRITEVERF);
+               if (tl == NULL)
+                       goto nfsmout;
                if (bcmp(nmp->nm_verf, tl,
                        NFSX_V3WRITEVERF)) {
                        bcopy(tl, nmp->nm_verf,
index 647fda5..c669e5f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: nfsm_subs.h,v 1.47 2019/01/18 13:59:18 bluhm Exp $    */
+/*     $OpenBSD: nfsm_subs.h,v 1.48 2024/04/30 17:04:23 miod Exp $     */
 /*     $NetBSD: nfsm_subs.h,v 1.10 1996/03/20 21:59:56 fvdl Exp $      */
 
 /*
 #define _NFS_NFSM_SUBS_H_
 
 struct nfsm_info {
-       struct mbuf      *nmi_mreq;
-       struct mbuf      *nmi_mrep;
+       struct mbuf     *nmi_mreq;
+       struct mbuf     *nmi_mrep;
 
-       struct proc      *nmi_procp;    /* XXX XXX XXX */
-       struct ucred     *nmi_cred;     /* XXX XXX XXX */
+       struct proc     *nmi_procp;     /* XXX XXX XXX */
+       struct ucred    *nmi_cred;      /* XXX XXX XXX */
 
        /* Setting up / Tearing down. */
-       struct mbuf      *nmi_md;
-       struct mbuf      *nmi_mb;
-       caddr_t           nmi_dpos;
+       struct mbuf     *nmi_md;
+       struct mbuf     *nmi_mb;
+       caddr_t          nmi_dpos;
 
-       int               nmi_v3;  
+       int              nmi_v3;  
+
+       int             *nmi_errorp;
 };
 
-#define nfsm_dissect(a, c, s) {                                                \
-       t1 = mtod(info.nmi_md, caddr_t) + info.nmi_md->m_len -          \
-           info.nmi_dpos;                                              \
-       if (t1 >= (s)) {                                                \
-               (a) = (c)(info.nmi_dpos);                               \
-               info.nmi_dpos += (s);                                   \
-       } else if ((t1 =                                                \
-                 nfsm_disct(&info.nmi_md, &info.nmi_dpos, (s), t1,     \
-                     &cp2)) != 0) {                                    \
-               error = t1;                                             \
-               m_freem(info.nmi_mrep);                                 \
-               goto nfsmout;                                           \
-       } else {                                                        \
-               (a) = (c)cp2;                                           \
-       }                                                               \
+static inline void *
+nfsm_dissect(struct nfsm_info *infop, int s)
+{
+       caddr_t ret;
+       int avail, error;
+
+       avail = mtod(infop->nmi_md, caddr_t) + infop->nmi_md->m_len -
+           infop->nmi_dpos;
+       if (avail >= s) {
+               ret = infop->nmi_dpos;
+               infop->nmi_dpos += s;
+               return ret;
+       }
+       error = nfsm_disct(&infop->nmi_md, &infop->nmi_dpos, s, avail, &ret);
+       if (error != 0) {
+               m_freem(infop->nmi_mrep);
+               *infop->nmi_errorp = error;
+               return NULL;
+       } else {
+               return ret;
+       }
 }
 
-#define nfsm_srvpostop_fh(f) {                                         \
-       tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED + NFSX_V3FH);   \
-       *tl++ = nfs_true;                                               \
-       *tl++ = txdr_unsigned(NFSX_V3FH);                               \
-       bcopy((f), tl, NFSX_V3FH);                      \
-}
+#define nfsm_rndup(a)  (((a)+3)&(~0x3))
 
-#define nfsm_mtofh(d, v, v3, f)        {                                       \
-       struct nfsnode *ttnp; nfsfh_t *ttfhp; int ttfhsize;             \
-       if (v3) {                                                       \
-               nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);           \
-               (f) = fxdr_unsigned(int, *tl);                          \
-       } else                                                          \
-               (f) = 1;                                                \
-       if (f) {                                                        \
-               nfsm_getfh(ttfhp, ttfhsize, (v3));                      \
-               if ((t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize,       \
-                   &ttnp)) != 0) {                                     \
-                       error = t1;                                     \
-                       m_freem(info.nmi_mrep);                         \
-                       goto nfsmout;                                   \
-               }                                                       \
-               (v) = NFSTOV(ttnp);                                     \
-       }                                                               \
-       if (v3) {                                                       \
-               nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);           \
-               if (f)                                                  \
-                       (f) = fxdr_unsigned(int, *tl);                  \
-               else if (fxdr_unsigned(int, *tl))                       \
-                       nfsm_adv(NFSX_V3FATTR);                         \
-       }                                                               \
-       if (f)                                                          \
-               nfsm_loadattr((v), NULL);                               \
+static inline int
+nfsm_adv(struct nfsm_info *infop, int s)
+{
+       int avail, error;
+       
+       avail = mtod(infop->nmi_md, caddr_t) + infop->nmi_md->m_len -
+           infop->nmi_dpos;
+       if (avail >= s) {
+               infop->nmi_dpos += s;
+               return 0;
+       }
+       error = nfs_adv(&infop->nmi_md, &infop->nmi_dpos, s, avail);
+       if (error != 0) {
+               m_freem(infop->nmi_mrep);
+               *infop->nmi_errorp = error;
+               return error;
+       }
+       return 0;
 }
 
-#define nfsm_getfh(f, s, v3) {                                         \
-       if (v3) {                                                       \
-               nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);           \
-               if (((s) = fxdr_unsigned(int, *tl)) <= 0 ||             \
-                       (s) > NFSX_V3FHMAX) {                           \
-                       m_freem(info.nmi_mrep);                         \
-                       error = EBADRPC;                                \
-                       goto nfsmout;                                   \
-               }                                                       \
-       } else                                                          \
-               (s) = NFSX_V2FH;                                        \
-       nfsm_dissect((f), nfsfh_t *, nfsm_rndup(s));                    \
+static inline int
+nfsm_postop_attr(struct nfsm_info *infop, struct vnode **vpp, int *attrflagp)
+{
+       uint32_t *tl;
+       struct vnode *ttvp;
+       int attrflag, error;
+
+       if (infop->nmi_mrep == NULL)
+               return 0;
+
+       ttvp = *vpp;
+       tl = (uint32_t *)nfsm_dissect(infop, NFSX_UNSIGNED);
+       if (tl == NULL)
+               return 1;       /* anything nonzero */
+       attrflag = fxdr_unsigned(int, *tl);
+       if (attrflag != 0) {
+               error = nfs_loadattrcache(&ttvp, &infop->nmi_md,
+                   &infop->nmi_dpos, NULL);
+               if (error != 0) {
+                       m_freem(infop->nmi_mrep);
+                       *infop->nmi_errorp = error;
+                       return error;
+               }
+               *vpp = ttvp;
+       }
+       *attrflagp = attrflag;
+       return 0;
 }
 
-#define nfsm_loadattr(v, a) {                                          \
-       struct vnode *ttvp = (v);                                       \
-       if ((t1 = nfs_loadattrcache(&ttvp, &info.nmi_md,                \
-           &info.nmi_dpos, (a))) != 0) {                               \
-               error = t1;                                             \
-               m_freem(info.nmi_mrep);                                 \
-               goto nfsmout;                                           \
-       }                                                               \
-       (v) = ttvp;                                                     \
+static inline int
+nfsm_strsiz(struct nfsm_info *infop, int *lenp, int maxlen)
+{
+       uint32_t *tl = (uint32_t *)nfsm_dissect(infop, NFSX_UNSIGNED);
+       int len;
+       if (tl == NULL)
+               return 1;
+       len = fxdr_unsigned(int32_t, *tl);
+       if (len < 0 || len > maxlen) {
+               m_freem(infop->nmi_mrep);
+               *infop->nmi_errorp = EBADRPC;
+               return 1;
+       }
+       *lenp = len;
+       return 0;
 }
 
-#define nfsm_postop_attr(v, f) { if (info.nmi_mrep != NULL) {          \
-       struct vnode *ttvp = (v);                                       \
-       nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);                   \
-       if (((f) = fxdr_unsigned(int, *tl)) != 0) {                     \
-               if ((t1 = nfs_loadattrcache(&ttvp, &info.nmi_md,        \
-                   &info.nmi_dpos, NULL)) != 0) {                      \
-                       error = t1;                                     \
-                       (f) = 0;                                        \
-                       m_freem(info.nmi_mrep);                         \
-                       goto nfsmout;                                   \
-               }                                                       \
-               (v) = ttvp;                                             \
-       }                                                               \
-} }
+static inline int
+nfsm_mtouio(struct nfsm_info *infop, struct uio *uiop, int len)
+{
+       int error;
 
-/* Used as (f) for nfsm_wcc_data() */
-#define NFSV3_WCCRATTR 0
-#define NFSV3_WCCCHK   1
+       if (len <= 0)
+               return 0;
 
-#define nfsm_wcc_data(v, f) do { if (info.nmi_mrep != NULL) {          \
-       struct timespec  _mtime;                                        \
-       int              ttattrf, ttretf = 0;                           \
-                                                                       \
-       nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);                   \
-       if (*tl == nfs_true) {                                          \
-               nfsm_dissect(tl, u_int32_t *, 6 * NFSX_UNSIGNED);       \
-               fxdr_nfsv3time(tl + 2, &_mtime);                        \
-               if (f) {                                                \
-                       ttretf = timespeccmp(&VTONFS(v)->n_mtime,       \
-                           &_mtime, !=);                               \
-               }                                                       \
-       }                                                               \
-       nfsm_postop_attr((v), ttattrf);                                 \
-       if (f) {                                                        \
-               (f) = ttretf;                                           \
-       } else {                                                        \
-               (f) = ttattrf;                                          \
-       }                                                               \
-} } while (0)
-
-#define nfsm_strsiz(s, m) {                                            \
-       nfsm_dissect(tl, u_int32_t *,NFSX_UNSIGNED);                    \
-       if (((s) = fxdr_unsigned(int32_t, *tl)) < 0 || (s) > (m)) {     \
-               m_freem(info.nmi_mrep);                                 \
-               error = EBADRPC;                                        \
-               goto nfsmout;                                           \
-       }                                                               \
-}
-
-#define nfsm_srvnamesiz(s) {                                           \
-       nfsm_dissect(tl, u_int32_t *,NFSX_UNSIGNED);                    \
-       if (((s) = fxdr_unsigned(int32_t, *tl)) > NFS_MAXNAMLEN)        \
-               error = NFSERR_NAMETOL;                                 \
-       if ((s) <= 0)                                                   \
-               error = EBADRPC;                                        \
-       if (error)                                                      \
-               nfsm_reply(0);                                          \
-}
-
-#define nfsm_mtouio(p, s)                                              \
-       if ((s) > 0 &&                                                  \
-           (t1 = nfsm_mbuftouio(&info.nmi_md, (p), (s),                \
-               &info.nmi_dpos)) != 0) {                                \
-               error = t1;                                             \
-               m_freem(info.nmi_mrep);                                 \
-               goto nfsmout;                                           \
+       error = nfsm_mbuftouio(&infop->nmi_md, uiop, len, &infop->nmi_dpos);
+       if (error != 0) {
+               m_freem(infop->nmi_mrep);
+               *infop->nmi_errorp = error;
+               return error;
        }
-
-#define nfsm_rndup(a)  (((a)+3)&(~0x3))
-
-#define nfsm_strtom(a, s, m)                                           \
-       if ((s) > (m)) {                                                \
-               m_freem(info.nmi_mreq);                                 \
-               error = ENAMETOOLONG;                                   \
-               goto nfsmout;                                           \
-       }                                                               \
-       nfsm_strtombuf(&info.nmi_mb, (a), (s))
-
-#define nfsm_reply(s) {                                                        \
-       nfsd->nd_repstat = error;                                       \
-       if (error && !(nfsd->nd_flag & ND_NFSV3))                       \
-          (void) nfs_rephead(0, nfsd, slp, error,                      \
-               &info.nmi_mreq, &info.nmi_mb);                          \
-       else                                                            \
-          (void) nfs_rephead((s), nfsd, slp, error,                    \
-               &info.nmi_mreq, &info.nmi_mb);                          \
-       if (info.nmi_mrep != NULL) {                                    \
-               m_freem(info.nmi_mrep);                                 \
-               info.nmi_mrep = NULL;                                   \
-       }                                                               \
-       *mrq = info.nmi_mreq;                                           \
-       if (error && (!(nfsd->nd_flag & ND_NFSV3) || error == EBADRPC)) \
-               return(0);                                              \
+       return 0;
 }
 
-#define nfsm_adv(s) {                                                  \
-       t1 = mtod(info.nmi_md, caddr_t) + info.nmi_md->m_len -          \
-           info.nmi_dpos;                                              \
-       if (t1 >= (s)) {                                                \
-               info.nmi_dpos += (s);                                   \
-       } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos,          \
-             (s), t1)) != 0) {                                         \
-               error = t1;                                             \
-               m_freem(info.nmi_mrep);                                 \
-               goto nfsmout;                                           \
-       }                                                               \
-}
-
-#define nfsm_srvmtofh(f) {                                             \
-       if (nfsd->nd_flag & ND_NFSV3) {                                 \
-               nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);           \
-               if (fxdr_unsigned(int, *tl) != NFSX_V3FH) {             \
-                       error = EBADRPC;                                \
-                       nfsm_reply(0);                                  \
-               }                                                       \
-       }                                                               \
-       nfsm_dissect(tl, u_int32_t *, NFSX_V3FH);                       \
-       bcopy(tl, (f), NFSX_V3FH);                      \
-       if ((nfsd->nd_flag & ND_NFSV3) == 0)                            \
-       nfsm_adv(NFSX_V2FH - NFSX_V3FH);                                \
+static inline int
+nfsm_strtom(struct nfsm_info *infop, char *str, size_t len, size_t maxlen)
+{
+       if (len > maxlen) {
+               m_freem(infop->nmi_mreq);
+               *infop->nmi_errorp = ENAMETOOLONG;
+               return 1;
+       }
+       nfsm_strtombuf(&infop->nmi_mb, str, len);
+       return 0;
 }
 
 #endif
index c8a635d..26fe4e3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: nfsnode.h,v 1.42 2021/03/11 13:31:35 jsg Exp $        */
+/*     $OpenBSD: nfsnode.h,v 1.43 2024/04/30 17:04:23 miod Exp $       */
 /*     $NetBSD: nfsnode.h,v 1.16 1996/02/18 11:54:04 fvdl Exp $        */
 
 /*
@@ -62,12 +62,6 @@ struct sillyrename {
  * There is a unique nfsnode allocated for each active file,
  * each current directory, each mounted-on file, text file, and the root.
  * An nfsnode is 'named' by its file handle. (nget/nfs_node.c)
- * If this structure exceeds 256 bytes (it is currently 256 using 4.4BSD-Lite
- * type definitions), file handles of > 32 bytes should probably be split out
- * into a separate malloc()'d data structure. (Reduce the size of nfsfh_t by
- * changing the definition in sys/mount.h of NFS_SMALLFH.)
- * NB: Hopefully the current order of the fields is such that everything will
- *     be well aligned and, therefore, tightly packed.
  */
 struct nfsnode {
        RB_ENTRY(nfsnode)       n_entry;        /* filehandle/node tree. */