From 42edf14f74e4d296cc417469a1c3042e42f8f686 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Thu, 16 Jul 2009 16:21:36 -0700 Subject: [PATCH] NFS - Marathon - completely refactor the nfsm_* macros. Completely refactor the nfsm_*() macros in nfsm_subs.h, converting all of them to procedures in nfsm_subs.c. Add a nfsm_info structure to track the persistent state that the code depends on, and remove all related local variables from the other bits of the NFS code. --- sys/vfs/nfs/nfs.h | 15 +- sys/vfs/nfs/nfs_serv.c | 1174 ++++++++++++++++++++---------------- sys/vfs/nfs/nfs_socket.c | 175 +++--- sys/vfs/nfs/nfs_subs.c | 3 +- sys/vfs/nfs/nfs_syscalls.c | 19 +- sys/vfs/nfs/nfs_vfsops.c | 62 +- sys/vfs/nfs/nfs_vnops.c | 877 ++++++++++++++------------- sys/vfs/nfs/nfsm_subs.c | 813 ++++++++++++++++++++++--- sys/vfs/nfs/nfsm_subs.h | 610 ++++--------------- 9 files changed, 2095 insertions(+), 1653 deletions(-) diff --git a/sys/vfs/nfs/nfs.h b/sys/vfs/nfs/nfs.h index bf80f832d6..6621ab6a6f 100644 --- a/sys/vfs/nfs/nfs.h +++ b/sys/vfs/nfs/nfs.h @@ -644,13 +644,6 @@ int nfs_doio (struct vnode *vp, struct bio *, struct thread *); int nfs_readlinkrpc (struct vnode *, struct uio *); int nfs_sigintr (struct nfsmount *, struct nfsreq *, struct thread *); int nfs_readdirplusrpc (struct vnode *, struct uio *); -int nfsm_disct (struct mbuf **, caddr_t *, int, int, caddr_t *); -void nfsm_srvfattr (struct nfsrv_descript *, struct vattr *, - struct nfs_fattr *); -void nfsm_srvwcc (struct nfsrv_descript *, int, struct vattr *, int, - struct vattr *, struct mbuf **, char **); -void nfsm_srvpostopattr (struct nfsrv_descript *, int, struct vattr *, - struct mbuf **, char **); int netaddr_match (int, union nethostaddr *, struct sockaddr *); int nfs_request (struct vnode *, struct mbuf *, int, struct thread *, struct ucred *, struct mbuf **, struct mbuf **, @@ -665,14 +658,12 @@ int nfs_request_processreply(struct nfsreq *rep, int error); -int nfs_loadattrcache (struct vnode **, struct mbuf **, caddr_t *, - struct vattr *, int); +int nfs_loadattrcache (struct vnode *, struct mbuf **, caddr_t *, + struct vattr *, int); int nfs_namei (struct nlookupdata *, struct ucred *, int, struct vnode **, struct vnode **, fhandle_t *, int, struct nfssvc_sock *, struct sockaddr *, struct mbuf **, caddr_t *, struct vnode **, struct thread *, int, int); -void nfsm_adj (struct mbuf *, int, int); -int nfsm_mbuftouio (struct mbuf **, struct uio *, int, caddr_t *); void nfsrv_initcache (void); int nfs_getauth (struct nfsmount *, struct nfsreq *, struct ucred *, char **, int *, char *, int *, NFSKERBKEY_T); @@ -695,9 +686,7 @@ int nfs_connect (struct nfsmount *, struct nfsreq *); void nfs_disconnect (struct nfsmount *); void nfs_safedisconnect (struct nfsmount *); int nfs_getattrcache (struct vnode *, struct vattr *); -int nfsm_strtmbuf (struct mbuf **, char **, const char *, long); int nfs_bioread (struct vnode *, struct uio *, int); -int nfsm_uiotombuf (struct uio *, struct mbuf **, int, caddr_t *); void nfsrv_init (int); void nfs_clearcommit (struct mount *); int nfsrv_errmap (struct nfsrv_descript *, int); diff --git a/sys/vfs/nfs/nfs_serv.c b/sys/vfs/nfs/nfs_serv.c index 220db22c64..6f37d667d5 100644 --- a/sys/vfs/nfs/nfs_serv.c +++ b/sys/vfs/nfs/nfs_serv.c @@ -149,32 +149,32 @@ int nfsrv3_access(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq) { - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; struct ucred *cred = &nfsd->nd_cr; struct vnode *vp = NULL; struct mount *mp = NULL; nfsfh_t nfh; fhandle_t *fhp; - u_int32_t *tl; - int32_t t1; - caddr_t bpos; int error = 0, rdonly, getret; - char *cp2; - struct mbuf *mb, *mreq, *mb2; struct vattr vattr, *vap = &vattr; u_long testmode, nfsmode; + struct nfsm_info info; + u_int32_t *tl; + + info.dpos = nfsd->nd_dpos; + info.md = nfsd->nd_md; + info.mrep = nfsd->nd_mrep; + info.mreq = NULL; nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + NEGREPLYOUT(nfsm_srvmtofh(&info, nfsd, fhp, &error)); + NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED)); error = nfsrv_fhtovp(fhp, 1, &mp, &vp, cred, slp, nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (error) { - nfsm_reply(NFSX_UNSIGNED); - nfsm_srvpostop_attr(1, NULL); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, NFSX_UNSIGNED, &error)); + nfsm_srvpostop_attr(&info, nfsd, 1, NULL); error = 0; goto nfsmout; } @@ -200,11 +200,13 @@ nfsrv3_access(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, getret = VOP_GETATTR(vp, vap); vput(vp); vp = NULL; - nfsm_reply(NFSX_POSTOPATTR(1) + NFSX_UNSIGNED); - nfsm_srvpostop_attr(getret, vap); - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_POSTOPATTR(1) + NFSX_UNSIGNED, &error)); + nfsm_srvpostop_attr(&info, nfsd, getret, vap); + tl = nfsm_build(&info, NFSX_UNSIGNED); *tl = txdr_unsigned(nfsmode); nfsmout: + *mrq = info.mreq; if (vp) vput(vp); return(error); @@ -217,9 +219,7 @@ int nfsrv_getattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq) { - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; struct ucred *cred = &nfsd->nd_cr; struct nfs_fattr *fp; struct vattr va; @@ -228,36 +228,39 @@ nfsrv_getattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct mount *mp = NULL; nfsfh_t nfh; fhandle_t *fhp; - u_int32_t *tl; - int32_t t1; - caddr_t bpos; int error = 0, rdonly; - char *cp2; - struct mbuf *mb, *mb2, *mreq; + struct nfsm_info info; + + info.mrep = nfsd->nd_mrep; + info.md = nfsd->nd_md; + info.dpos = nfsd->nd_dpos; + info.mreq = NULL; nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); + NEGREPLYOUT(nfsm_srvmtofh(&info, nfsd, fhp, &error)); error = nfsrv_fhtovp(fhp, 1, &mp, &vp, cred, slp, nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (error) { - nfsm_reply(0); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, 0, &error)); error = 0; goto nfsmout; } error = VOP_GETATTR(vp, vap); vput(vp); vp = NULL; - nfsm_reply(NFSX_FATTR(nfsd->nd_flag & ND_NFSV3)); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_FATTR(nfsd->nd_flag & ND_NFSV3), &error)); if (error) { error = 0; goto nfsmout; } - nfsm_build(fp, struct nfs_fattr *, NFSX_FATTR(nfsd->nd_flag & ND_NFSV3)); - nfsm_srvfillattr(vap, fp); + fp = nfsm_build(&info, NFSX_FATTR(nfsd->nd_flag & ND_NFSV3)); + nfsm_srvfattr(nfsd, vap, fp); /* fall through */ nfsmout: + *mrq = info.mreq; if (vp) vput(vp); return(error); @@ -270,9 +273,7 @@ int nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq) { - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; struct ucred *cred = &nfsd->nd_cr; struct vattr va, preat; struct vattr *vap = &va; @@ -283,28 +284,31 @@ nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, nfsfh_t nfh; fhandle_t *fhp; u_int32_t *tl; - int32_t t1; - caddr_t bpos; int error = 0, rdonly, preat_ret = 1, postat_ret = 1; - int v3 = (nfsd->nd_flag & ND_NFSV3), gcheck = 0; - char *cp2; - struct mbuf *mb, *mb2, *mreq; + int gcheck = 0; struct timespec guard; + struct nfsm_info info; + + info.mrep = nfsd->nd_mrep; + info.mreq = NULL; + info.md = nfsd->nd_md; + info.dpos = nfsd->nd_dpos; + info.v3 = (nfsd->nd_flag & ND_NFSV3); nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); + NEGREPLYOUT(nfsm_srvmtofh(&info, nfsd, fhp, &error)); VATTR_NULL(vap); - if (v3) { - nfsm_srvsattr(vap); - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + if (info.v3) { + ERROROUT(nfsm_srvsattr(&info, vap)); + NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED)); gcheck = fxdr_unsigned(int, *tl); if (gcheck) { - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + NULLOUT(tl = nfsm_dissect(&info, 2 * NFSX_UNSIGNED)); fxdr_nfsv3time(tl, &guard); } } else { - nfsm_dissect(sp, struct nfsv2_sattr *, NFSX_V2SATTR); + NULLOUT(sp = nfsm_dissect(&info, NFSX_V2SATTR)); /* * Nah nah nah nah na nah * There is a bug in the Sun client that puts 0xffff in the mode @@ -340,8 +344,10 @@ nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, error = nfsrv_fhtovp(fhp, 1, &mp, &vp, cred, slp, nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (error) { - nfsm_reply(2 * NFSX_UNSIGNED); - nfsm_srvwcc_data(preat_ret, &preat, postat_ret, vap); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + 2 * NFSX_UNSIGNED, &error)); + nfsm_srvwcc_data(&info, nfsd, preat_ret, &preat, + postat_ret, vap); error = 0; goto nfsmout; } @@ -350,7 +356,7 @@ nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, * vp now an active resource, pay careful attention to cleanup */ - if (v3) { + if (info.v3) { error = preat_ret = VOP_GETATTR(vp, &preat); if (!error && gcheck && (preat.va_ctime.tv_sec != guard.tv_sec || @@ -359,8 +365,10 @@ nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, if (error) { vput(vp); vp = NULL; - nfsm_reply(NFSX_WCCDATA(v3)); - nfsm_srvwcc_data(preat_ret, &preat, postat_ret, vap); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_WCCDATA(info.v3), &error)); + nfsm_srvwcc_data(&info, nfsd, preat_ret, &preat, + postat_ret, vap); error = 0; goto nfsmout; } @@ -391,18 +399,21 @@ nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, out: vput(vp); vp = NULL; - nfsm_reply(NFSX_WCCORFATTR(v3)); - if (v3) { - nfsm_srvwcc_data(preat_ret, &preat, postat_ret, vap); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_WCCORFATTR(info.v3), &error)); + if (info.v3) { + nfsm_srvwcc_data(&info, nfsd, preat_ret, &preat, + postat_ret, vap); error = 0; goto nfsmout; } else { - nfsm_build(fp, struct nfs_fattr *, NFSX_V2FATTR); - nfsm_srvfillattr(vap, fp); + fp = nfsm_build(&info, NFSX_V2FATTR); + nfsm_srvfattr(nfsd, vap, fp); } /* fall through */ nfsmout: + *mrq = info.mreq; if (vp) vput(vp); return(error); @@ -415,9 +426,7 @@ int nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq) { - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; struct ucred *cred = &nfsd->nd_cr; struct nfs_fattr *fp; struct nlookupdata nd; @@ -426,15 +435,16 @@ nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct nchandle nch; nfsfh_t nfh; fhandle_t *fhp; - caddr_t cp; - u_int32_t *tl; - int32_t t1; - caddr_t bpos; int error = 0, len, dirattr_ret = 1; - int v3 = (nfsd->nd_flag & ND_NFSV3), pubflag; - char *cp2; - struct mbuf *mb, *mb2, *mreq; + int pubflag; struct vattr va, dirattr, *vap = &va; + struct nfsm_info info; + + info.mrep = nfsd->nd_mrep; + info.mreq = NULL; + info.md = nfsd->nd_md; + info.dpos = nfsd->nd_dpos; + info.v3 = (nfsd->nd_flag & ND_NFSV3); nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); nlookup_zero(&nd); @@ -442,13 +452,13 @@ nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, vp = NULL; fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - nfsm_srvnamesiz(len); + NEGREPLYOUT(nfsm_srvmtofh(&info, nfsd, fhp, &error)); + NEGREPLYOUT(len = nfsm_srvnamesiz(&info, &error)); pubflag = nfs_ispublicfh(fhp); error = nfs_namei(&nd, cred, 0, NULL, &vp, - fhp, len, slp, nam, &md, &dpos, + fhp, len, slp, nam, &info.md, &info.dpos, &dirp, td, (nfsd->nd_flag & ND_KERBAUTH), pubflag); /* @@ -458,13 +468,14 @@ nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, if (error) { if (dirp) { - if (v3) + if (info.v3) dirattr_ret = VOP_GETATTR(dirp, &dirattr); vrele(dirp); dirp = NULL; } - nfsm_reply(NFSX_POSTOPATTR(v3)); - nfsm_srvpostop_attr(dirattr_ret, &dirattr); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_POSTOPATTR(info.v3), &error)); + nfsm_srvpostop_attr(&info, nfsd, dirattr_ret, &dirattr); error = 0; goto nfsmout; } @@ -532,7 +543,7 @@ nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, } if (dirp) { - if (v3) + if (info.v3) dirattr_ret = VOP_GETATTR(dirp, &dirattr); vrele(dirp); dirp = NULL; @@ -545,8 +556,9 @@ nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, */ if (error) { - nfsm_reply(NFSX_POSTOPATTR(v3)); - nfsm_srvpostop_attr(dirattr_ret, &dirattr); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_POSTOPATTR(info.v3), &error)); + nfsm_srvpostop_attr(&info, nfsd, dirattr_ret, &dirattr); error = 0; goto nfsmout; } @@ -569,22 +581,27 @@ nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, vput(vp); vp = NULL; - nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPORFATTR(v3) + NFSX_POSTOPATTR(v3)); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_SRVFH(info.v3) + + NFSX_POSTOPORFATTR(info.v3) + + NFSX_POSTOPATTR(info.v3), + &error)); if (error) { - nfsm_srvpostop_attr(dirattr_ret, &dirattr); + nfsm_srvpostop_attr(&info, nfsd, dirattr_ret, &dirattr); error = 0; goto nfsmout; } - nfsm_srvfhtom(fhp, v3); - if (v3) { - nfsm_srvpostop_attr(0, vap); - nfsm_srvpostop_attr(dirattr_ret, &dirattr); + nfsm_srvfhtom(&info, fhp); + if (info.v3) { + nfsm_srvpostop_attr(&info, nfsd, 0, vap); + nfsm_srvpostop_attr(&info, nfsd, dirattr_ret, &dirattr); } else { - nfsm_build(fp, struct nfs_fattr *, NFSX_V2FATTR); - nfsm_srvfillattr(vap, fp); + fp = nfsm_build(&info, NFSX_V2FATTR); + nfsm_srvfattr(nfsd, vap, fp); } nfsmout: + *mrq = info.mreq; if (dirp) vrele(dirp); nlookup_done(&nd); /* may be called twice */ @@ -600,25 +617,26 @@ int nfsrv_readlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq) { - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; struct ucred *cred = &nfsd->nd_cr; struct iovec iv[(NFS_MAXPATHLEN+MLEN-1)/MLEN]; struct iovec *ivp = iv; u_int32_t *tl; - int32_t t1; - caddr_t bpos; int error = 0, rdonly, i, tlen, len, getret; - int v3 = (nfsd->nd_flag & ND_NFSV3); - char *cp2; - struct mbuf *mb, *mb2, *mp1, *mp2, *mp3, *mreq; + struct mbuf *mp1, *mp2, *mp3; struct vnode *vp = NULL; struct mount *mp = NULL; struct vattr attr; nfsfh_t nfh; fhandle_t *fhp; struct uio io, *uiop = &io; + struct nfsm_info info; + + info.mrep = nfsd->nd_mrep; + info.mreq = NULL; + info.md = nfsd->nd_md; + info.dpos = nfsd->nd_dpos; + info.v3 = (nfsd->nd_flag & ND_NFSV3); nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); #ifndef nolint @@ -626,7 +644,7 @@ nfsrv_readlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, #endif mp3 = NULL; fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); + NEGREPLYOUT(nfsm_srvmtofh(&info, nfsd, fhp, &error)); len = 0; i = 0; while (len < NFS_MAXPATHLEN) { @@ -658,13 +676,14 @@ nfsrv_readlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, error = nfsrv_fhtovp(fhp, 1, &mp, &vp, cred, slp, nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (error) { - nfsm_reply(2 * NFSX_UNSIGNED); - nfsm_srvpostop_attr(1, NULL); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + 2 * NFSX_UNSIGNED, &error)); + nfsm_srvpostop_attr(&info, nfsd, 1, NULL); error = 0; goto nfsmout; } if (vp->v_type != VLNK) { - if (v3) + if (info.v3) error = EINVAL; else error = ENXIO; @@ -675,9 +694,11 @@ out: getret = VOP_GETATTR(vp, &attr); vput(vp); vp = NULL; - nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_UNSIGNED); - if (v3) { - nfsm_srvpostop_attr(getret, &attr); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_POSTOPATTR(info.v3) + NFSX_UNSIGNED, + &error)); + if (info.v3) { + nfsm_srvpostop_attr(&info, nfsd, getret, &attr); if (error) { error = 0; goto nfsmout; @@ -688,11 +709,12 @@ out: tlen = nfsm_rndup(len); nfsm_adj(mp3, NFS_MAXPATHLEN-tlen, tlen-len); } - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); + tl = nfsm_build(&info, NFSX_UNSIGNED); *tl = txdr_unsigned(len); - mb->m_next = mp3; + info.mb->m_next = mp3; mp3 = NULL; nfsmout: + *mrq = info.mreq; if (mp3) m_freem(mp3); if (vp) @@ -707,22 +729,17 @@ int nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq) { - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; + struct nfsm_info info; struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; struct ucred *cred = &nfsd->nd_cr; struct iovec *iv; struct iovec *iv2; struct mbuf *m; struct nfs_fattr *fp; u_int32_t *tl; - int32_t t1; int i; - caddr_t bpos; + int reqlen; int error = 0, rdonly, cnt, len, left, siz, tlen, getret; - int v3 = (nfsd->nd_flag & ND_NFSV3), reqlen; - char *cp2; - struct mbuf *mb, *mb2, *mreq; struct mbuf *m2; struct vnode *vp = NULL; struct mount *mp = NULL; @@ -734,17 +751,24 @@ nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, off_t off; int ioflag = 0; + info.mrep = nfsd->nd_mrep; + info.mreq = NULL; + info.md = nfsd->nd_md; + info.dpos = nfsd->nd_dpos; + info.v3 = (nfsd->nd_flag & ND_NFSV3); + nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - if (v3) { - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + NEGREPLYOUT(nfsm_srvmtofh(&info, nfsd, fhp, &error)); + if (info.v3) { + NULLOUT(tl = nfsm_dissect(&info, 2 * NFSX_UNSIGNED)); off = fxdr_hyper(tl); } else { - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED)); off = (off_t)fxdr_unsigned(u_int32_t, *tl); } - nfsm_srvstrsiz(reqlen, NFS_SRVMAXDATA(nfsd)); + NEGREPLYOUT(reqlen = nfsm_srvstrsiz(&info, + NFS_SRVMAXDATA(nfsd), &error)); /* * Reference vp. If an error occurs, vp will be invalid, but we @@ -756,14 +780,15 @@ nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (error) { vp = NULL; - nfsm_reply(2 * NFSX_UNSIGNED); - nfsm_srvpostop_attr(1, NULL); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + 2 * NFSX_UNSIGNED, &error)); + nfsm_srvpostop_attr(&info, nfsd, 1, NULL); error = 0; goto nfsmout; } if (vp->v_type != VREG) { - if (v3) + if (info.v3) error = EINVAL; else error = (vp->v_type == VDIR) ? EISDIR : EACCES; @@ -778,8 +803,9 @@ nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, if (error) { vput(vp); vp = NULL; - nfsm_reply(NFSX_POSTOPATTR(v3)); - nfsm_srvpostop_attr(getret, vap); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_POSTOPATTR(info.v3), &error)); + nfsm_srvpostop_attr(&info, nfsd, getret, vap); error = 0; goto nfsmout; } @@ -850,14 +876,17 @@ nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, ioflag |= nh->nh_seqcount << IO_SEQSHIFT; } - nfsm_reply(NFSX_POSTOPORFATTR(v3) + 3 * NFSX_UNSIGNED+nfsm_rndup(cnt)); - if (v3) { - nfsm_build(tl, u_int32_t *, NFSX_V3FATTR + 4 * NFSX_UNSIGNED); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_POSTOPORFATTR(info.v3) + + 3 * NFSX_UNSIGNED + nfsm_rndup(cnt), + &error)); + if (info.v3) { + tl = nfsm_build(&info, NFSX_V3FATTR + 4 * NFSX_UNSIGNED); *tl++ = nfs_true; fp = (struct nfs_fattr *)tl; tl += (NFSX_V3FATTR / sizeof (u_int32_t)); } else { - nfsm_build(tl, u_int32_t *, NFSX_V2FATTR + NFSX_UNSIGNED); + tl = nfsm_build(&info, NFSX_V2FATTR + NFSX_UNSIGNED); fp = (struct nfs_fattr *)tl; tl += (NFSX_V2FATTR / sizeof (u_int32_t)); } @@ -867,7 +896,7 @@ nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, * Generate the mbuf list with the uio_iov ref. to it. */ i = 0; - m = m2 = mb; + m = m2 = info.mb; while (left > 0) { siz = min(M_TRAILINGSPACE(m), left); if (siz > 0) { @@ -884,7 +913,7 @@ nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, MALLOC(iv, struct iovec *, i * sizeof (struct iovec), M_TEMP, M_WAITOK); uiop->uio_iov = iv2 = iv; - m = mb; + m = info.mb; left = len; i = 0; while (left > 0) { @@ -913,11 +942,14 @@ nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, if (error || (getret = VOP_GETATTR(vp, vap))) { if (!error) error = getret; - m_freem(mreq); + m_freem(info.mreq); + info.mreq = NULL; vput(vp); vp = NULL; - nfsm_reply(NFSX_POSTOPATTR(v3)); - nfsm_srvpostop_attr(getret, vap); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_POSTOPATTR(info.v3), + &error)); + nfsm_srvpostop_attr(&info, nfsd, getret, vap); error = 0; goto nfsmout; } @@ -926,13 +958,13 @@ nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, } vput(vp); vp = NULL; - nfsm_srvfillattr(vap, fp); + nfsm_srvfattr(nfsd, vap, fp); tlen = len - uiop->uio_resid; cnt = cnt < tlen ? cnt : tlen; tlen = nfsm_rndup(cnt); if (len != tlen || tlen != cnt) - nfsm_adj(mb, len - tlen, tlen - cnt); - if (v3) { + nfsm_adj(info.mb, len - tlen, tlen - cnt); + if (info.v3) { *tl++ = txdr_unsigned(cnt); if (len < reqlen) *tl++ = nfs_true; @@ -941,6 +973,7 @@ nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, } *tl = txdr_unsigned(cnt); nfsmout: + *mrq = info.mreq; if (vp) vput(vp); return(error); @@ -953,9 +986,7 @@ int nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq) { - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; struct ucred *cred = &nfsd->nd_cr; struct iovec *ivp; int i, cnt; @@ -965,36 +996,37 @@ nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct vattr va, forat; struct vattr *vap = &va; u_int32_t *tl; - int32_t t1; - caddr_t bpos; int error = 0, rdonly, len, forat_ret = 1; int ioflags, aftat_ret = 1, retlen, zeroing, adjust; int stable = NFSV3WRITE_FILESYNC; - int v3 = (nfsd->nd_flag & ND_NFSV3); - char *cp2; - struct mbuf *mb, *mb2, *mreq; struct vnode *vp = NULL; struct mount *mp = NULL; nfsfh_t nfh; fhandle_t *fhp; struct uio io, *uiop = &io; + struct nfsm_info info; off_t off; + info.mrep = nfsd->nd_mrep; + info.mreq = NULL; + info.md = nfsd->nd_md; + info.dpos = nfsd->nd_dpos; + info.v3 = (nfsd->nd_flag & ND_NFSV3); + nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); - if (mrep == NULL) { - *mrq = NULL; + if (info.mrep == NULL) { error = 0; goto nfsmout; } fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - if (v3) { - nfsm_dissect(tl, u_int32_t *, 5 * NFSX_UNSIGNED); + NEGREPLYOUT(nfsm_srvmtofh(&info, nfsd, fhp, &error)); + if (info.v3) { + NULLOUT(tl = nfsm_dissect(&info, 5 * NFSX_UNSIGNED)); off = fxdr_hyper(tl); tl += 3; stable = fxdr_unsigned(int, *tl++); } else { - nfsm_dissect(tl, u_int32_t *, 4 * NFSX_UNSIGNED); + NULLOUT(tl = nfsm_dissect(&info, 4 * NFSX_UNSIGNED)); off = (off_t)fxdr_unsigned(u_int32_t, *++tl); tl += 2; if (nfs_async) @@ -1010,14 +1042,14 @@ nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, */ if (len > 0) { zeroing = 1; - mp1 = mrep; + mp1 = info.mrep; while (mp1) { - if (mp1 == md) { + if (mp1 == info.md) { zeroing = 0; - adjust = dpos - mtod(mp1, caddr_t); + adjust = info.dpos - mtod(mp1, caddr_t); mp1->m_len -= adjust; if (mp1->m_len > 0 && adjust > 0) - NFSMADV(mp1, adjust); + mp1->m_data += adjust; } if (zeroing) mp1->m_len = 0; @@ -1035,8 +1067,10 @@ nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, } if (len > NFS_MAXDATA || len < 0 || i < len) { error = EIO; - nfsm_reply(2 * NFSX_UNSIGNED); - nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + 2 * NFSX_UNSIGNED, &error)); + nfsm_srvwcc_data(&info, nfsd, forat_ret, &forat, + aftat_ret, vap); error = 0; goto nfsmout; } @@ -1044,15 +1078,17 @@ nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (error) { vp = NULL; - nfsm_reply(2 * NFSX_UNSIGNED); - nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + 2 * NFSX_UNSIGNED, &error)); + nfsm_srvwcc_data(&info, nfsd, forat_ret, &forat, + aftat_ret, vap); error = 0; goto nfsmout; } - if (v3) + if (info.v3) forat_ret = VOP_GETATTR(vp, &forat); if (vp->v_type != VREG) { - if (v3) + if (info.v3) error = EINVAL; else error = (vp->v_type == VDIR) ? EISDIR : EACCES; @@ -1063,8 +1099,10 @@ nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, if (error) { vput(vp); vp = NULL; - nfsm_reply(NFSX_WCCDATA(v3)); - nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_WCCDATA(info.v3), &error)); + nfsm_srvwcc_data(&info, nfsd, forat_ret, &forat, + aftat_ret, vap); error = 0; goto nfsmout; } @@ -1074,7 +1112,7 @@ nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, M_WAITOK); uiop->uio_iov = iv = ivp; uiop->uio_iovcnt = cnt; - mp1 = mrep; + mp1 = info.mrep; while (mp1) { if (mp1->m_len > 0) { ivp->iov_base = mtod(mp1, caddr_t); @@ -1111,15 +1149,19 @@ nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, vp = NULL; if (!error) error = aftat_ret; - nfsm_reply(NFSX_PREOPATTR(v3) + NFSX_POSTOPORFATTR(v3) + - 2 * NFSX_UNSIGNED + NFSX_WRITEVERF(v3)); - if (v3) { - nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_PREOPATTR(info.v3) + + NFSX_POSTOPORFATTR(info.v3) + + 2 * NFSX_UNSIGNED + NFSX_WRITEVERF(info.v3), + &error)); + if (info.v3) { + nfsm_srvwcc_data(&info, nfsd, forat_ret, &forat, + aftat_ret, vap); if (error) { error = 0; goto nfsmout; } - nfsm_build(tl, u_int32_t *, 4 * NFSX_UNSIGNED); + tl = nfsm_build(&info, 4 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(retlen); /* * If nfs_async is set, then pretend the write was FILESYNC. @@ -1138,10 +1180,11 @@ nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, *tl++ = txdr_unsigned(nfsver.tv_sec); *tl = txdr_unsigned(nfsver.tv_nsec / 1000); } else { - nfsm_build(fp, struct nfs_fattr *, NFSX_V2FATTR); - nfsm_srvfillattr(vap, fp); + fp = nfsm_build(&info, NFSX_V2FATTR); + nfsm_srvfattr(nfsd, vap, fp); } nfsmout: + *mrq = info.mreq; if (vp) vput(vp); return(error); @@ -1167,16 +1210,14 @@ nfsrv_writegather(struct nfsrv_descript **ndp, struct nfssvc_sock *slp, struct ucred *cred; struct vattr va, forat; u_int32_t *tl; - int32_t t1; - caddr_t bpos, dpos; int error = 0, rdonly, len, forat_ret = 1; - int ioflags, aftat_ret = 1, adjust, v3, zeroing; - char *cp2; - struct mbuf *mb, *mb2, *mreq, *mrep, *md, *mp1; + int ioflags, aftat_ret = 1, adjust, zeroing; + struct mbuf *mp1; struct vnode *vp = NULL; struct mount *mp = NULL; struct uio io, *uiop = &io; u_quad_t cur_usec; + struct nfsm_info info; nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); #ifndef nolint @@ -1187,29 +1228,30 @@ nfsrv_writegather(struct nfsrv_descript **ndp, struct nfssvc_sock *slp, if (*ndp) { nfsd = *ndp; *ndp = NULL; - mrep = nfsd->nd_mrep; - md = nfsd->nd_md; - dpos = nfsd->nd_dpos; + info.mrep = nfsd->nd_mrep; + info.mreq = NULL; + info.md = nfsd->nd_md; + info.dpos = nfsd->nd_dpos; + info.v3 = (nfsd->nd_flag & ND_NFSV3); cred = &nfsd->nd_cr; - v3 = (nfsd->nd_flag & ND_NFSV3); LIST_INIT(&nfsd->nd_coalesce); nfsd->nd_mreq = NULL; nfsd->nd_stable = NFSV3WRITE_FILESYNC; cur_usec = nfs_curusec(); nfsd->nd_time = cur_usec + - (v3 ? nfsrvw_procrastinate_v3 : nfsrvw_procrastinate); + (info.v3 ? nfsrvw_procrastinate_v3 : nfsrvw_procrastinate); /* * Now, get the write header.. */ - nfsm_srvmtofh(&nfsd->nd_fh); - if (v3) { - nfsm_dissect(tl, u_int32_t *, 5 * NFSX_UNSIGNED); + NEGREPLYOUT(nfsm_srvmtofh(&info, nfsd, &nfsd->nd_fh, &error)); + if (info.v3) { + NULLOUT(tl = nfsm_dissect(&info, 5 * NFSX_UNSIGNED)); nfsd->nd_off = fxdr_hyper(tl); tl += 3; nfsd->nd_stable = fxdr_unsigned(int, *tl++); } else { - nfsm_dissect(tl, u_int32_t *, 4 * NFSX_UNSIGNED); + NULLOUT(tl = nfsm_dissect(&info, 4 * NFSX_UNSIGNED)); nfsd->nd_off = (off_t)fxdr_unsigned(u_int32_t, *++tl); tl += 2; if (nfs_async) @@ -1225,14 +1267,14 @@ nfsrv_writegather(struct nfsrv_descript **ndp, struct nfssvc_sock *slp, */ zeroing = 1; i = 0; - mp1 = mrep; + mp1 = info.mrep; while (mp1) { - if (mp1 == md) { + if (mp1 == info.md) { zeroing = 0; - adjust = dpos - mtod(mp1, caddr_t); + adjust = info.dpos - mtod(mp1, caddr_t); mp1->m_len -= adjust; if (mp1->m_len > 0 && adjust > 0) - NFSMADV(mp1, adjust); + mp1->m_data += adjust; } if (zeroing) mp1->m_len = 0; @@ -1247,12 +1289,15 @@ nfsrv_writegather(struct nfsrv_descript **ndp, struct nfssvc_sock *slp, } if (len > NFS_MAXDATA || len < 0 || i < len) { nfsmout: - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; error = EIO; - nfsm_writereply(2 * NFSX_UNSIGNED, v3); - if (v3) - nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, &va); - nfsd->nd_mreq = mreq; + nfsm_writereply(&info, nfsd, slp, error, 2 * NFSX_UNSIGNED); + if (info.v3) { + nfsm_srvwcc_data(&info, nfsd, forat_ret, &forat, + aftat_ret, &va); + } + nfsd->nd_mreq = info.mreq; nfsd->nd_mrep = NULL; nfsd->nd_time = 0; } @@ -1323,18 +1368,18 @@ loop1: LIST_REMOVE(nfsd, nd_tq); LIST_REMOVE(nfsd, nd_hash); crit_exit(); - mrep = nfsd->nd_mrep; + info.mrep = nfsd->nd_mrep; + info.v3 = (nfsd->nd_flag & ND_NFSV3); nfsd->nd_mrep = NULL; cred = &nfsd->nd_cr; - v3 = (nfsd->nd_flag & ND_NFSV3); forat_ret = aftat_ret = 1; error = nfsrv_fhtovp(&nfsd->nd_fh, 1, &mp, &vp, cred, slp, nfsd->nd_nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (!error) { - if (v3) + if (info.v3) forat_ret = VOP_GETATTR(vp, &forat); if (vp->v_type != VREG) { - if (v3) + if (info.v3) error = EINVAL; else error = (vp->v_type == VDIR) ? EISDIR : EACCES; @@ -1358,7 +1403,7 @@ loop1: uiop->uio_offset = nfsd->nd_off; uiop->uio_resid = nfsd->nd_eoff - nfsd->nd_off; if (uiop->uio_resid > 0) { - mp1 = mrep; + mp1 = info.mrep; i = 0; while (mp1) { if (mp1->m_len > 0) @@ -1369,7 +1414,7 @@ loop1: MALLOC(iov, struct iovec *, i * sizeof (struct iovec), M_TEMP, M_WAITOK); uiop->uio_iov = ivp = iov; - mp1 = mrep; + mp1 = info.mrep; while (mp1) { if (mp1->m_len > 0) { ivp->iov_base = mtod(mp1, caddr_t); @@ -1384,7 +1429,8 @@ loop1: } FREE((caddr_t)iov, M_TEMP); } - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; if (vp) { aftat_ret = VOP_GETATTR(vp, &va); vput(vp); @@ -1399,17 +1445,22 @@ loop1: do { NFS_DPF(WG, ("R%03x", nfsd->nd_retxid & 0xfff)); if (error) { - nfsm_writereply(NFSX_WCCDATA(v3), v3); - if (v3) { - nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, &va); + nfsm_writereply(&info, nfsd, slp, error, + NFSX_WCCDATA(info.v3)); + if (info.v3) { + nfsm_srvwcc_data(&info, nfsd, forat_ret, &forat, + aftat_ret, &va); } } else { - nfsm_writereply(NFSX_PREOPATTR(v3) + - NFSX_POSTOPORFATTR(v3) + 2 * NFSX_UNSIGNED + - NFSX_WRITEVERF(v3), v3); - if (v3) { - nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, &va); - nfsm_build(tl, u_int32_t *, 4 * NFSX_UNSIGNED); + nfsm_writereply(&info, nfsd, slp, error, + NFSX_PREOPATTR(info.v3) + + NFSX_POSTOPORFATTR(info.v3) + + 2 * NFSX_UNSIGNED + + NFSX_WRITEVERF(info.v3)); + if (info.v3) { + nfsm_srvwcc_data(&info, nfsd, forat_ret, &forat, + aftat_ret, &va); + tl = nfsm_build(&info, 4 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(nfsd->nd_len); *tl++ = txdr_unsigned(swp->nd_stable); /* @@ -1422,11 +1473,11 @@ loop1: *tl++ = txdr_unsigned(nfsver.tv_sec); *tl = txdr_unsigned(nfsver.tv_nsec / 1000); } else { - nfsm_build(fp, struct nfs_fattr *, NFSX_V2FATTR); - nfsm_srvfillattr(&va, fp); + fp = nfsm_build(&info, NFSX_V2FATTR); + nfsm_srvfattr(nfsd, &va, fp); } } - nfsd->nd_mreq = mreq; + nfsd->nd_mreq = info.mreq; if (nfsd->nd_mrep) panic("nfsrv_write: nd_mrep not free"); @@ -1528,9 +1579,7 @@ int nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq) { - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; struct ucred *cred = &nfsd->nd_cr; struct nfs_fattr *fp; struct vattr va, dirfor, diraft; @@ -1538,14 +1587,10 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct nfsv2_sattr *sp; u_int32_t *tl; struct nlookupdata nd; - int32_t t1; - caddr_t bpos; int error = 0, len, tsize, dirfor_ret = 1, diraft_ret = 1; udev_t rdev = NOUDEV; - int v3 = (nfsd->nd_flag & ND_NFSV3), how, exclusive_flag = 0; caddr_t cp; - char *cp2; - struct mbuf *mb, *mb2, *mreq; + int how, exclusive_flag = 0; struct vnode *dirp; struct vnode *dvp; struct vnode *vp; @@ -1554,6 +1599,7 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, fhandle_t *fhp; u_quad_t tempsize; u_char cverf[NFSX_V3CREATEVERF]; + struct nfsm_info info; nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); nlookup_zero(&nd); @@ -1561,9 +1607,15 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, dvp = NULL; vp = NULL; + info.mrep = nfsd->nd_mrep; + info.mreq = NULL; + info.md = nfsd->nd_md; + info.dpos = nfsd->nd_dpos; + info.v3 = (nfsd->nd_flag & ND_NFSV3); + fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - nfsm_srvnamesiz(len); + NEGREPLYOUT(nfsm_srvmtofh(&info, nfsd, fhp, &error)); + NEGREPLYOUT(len = nfsm_srvnamesiz(&info, &error)); /* * Call namei and do initial cleanup to get a few things @@ -1575,12 +1627,12 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, * prior to calling nfsm_reply ( which might goto nfsmout ). */ error = nfs_namei(&nd, cred, NLC_CREATE, &dvp, &vp, - fhp, len, slp, nam, &md, &dpos, &dirp, + fhp, len, slp, nam, &info.md, &info.dpos, &dirp, td, (nfsd->nd_flag & ND_KERBAUTH), FALSE); mp = vfs_getvfs(&fhp->fh_fsid); if (dirp) { - if (v3) { + if (info.v3) { dirfor_ret = VOP_GETATTR(dirp, &dirfor); } else { vrele(dirp); @@ -1588,8 +1640,10 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, } } if (error) { - nfsm_reply(NFSX_WCCDATA(v3)); - nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_WCCDATA(info.v3), &error)); + nfsm_srvwcc_data(&info, nfsd, dirfor_ret, &dirfor, + diraft_ret, &diraft); error = 0; goto nfsmout; } @@ -1608,8 +1662,8 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, */ VATTR_NULL(vap); - if (v3) { - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + if (info.v3) { + NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED)); how = fxdr_unsigned(int, *tl); switch (how) { case NFSV3CREATE_GUARDED: @@ -1619,17 +1673,17 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, } /* fall through */ case NFSV3CREATE_UNCHECKED: - nfsm_srvsattr(vap); + ERROROUT(nfsm_srvsattr(&info, vap)); break; case NFSV3CREATE_EXCLUSIVE: - nfsm_dissect(cp, caddr_t, NFSX_V3CREATEVERF); + NULLOUT(cp = nfsm_dissect(&info, NFSX_V3CREATEVERF)); bcopy(cp, cverf, NFSX_V3CREATEVERF); exclusive_flag = 1; break; }; vap->va_type = VREG; } else { - nfsm_dissect(sp, struct nfsv2_sattr *, NFSX_V2SATTR); + NULLOUT(sp = nfsm_dissect(&info, NFSX_V2SATTR)); vap->va_type = IFTOVT(fxdr_unsigned(u_int32_t, sp->sa_mode)); if (vap->va_type == VNON) vap->va_type = VREG; @@ -1729,7 +1783,8 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, nd.ni_dvp = NULL; if (error != 0) { - nfsm_reply(0); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + 0, &error)); /* fall through on certain errors */ } nfsrv_object_create(nd.ni_vp); @@ -1760,7 +1815,7 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, if (!error) error = VOP_GETATTR(vp, vap); } - if (v3) { + if (info.v3) { if (exclusive_flag && !error && bcmp(cverf, (caddr_t)&vap->va_atime, NFSX_V3CREATEVERF)) error = EEXIST; @@ -1768,27 +1823,32 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, vrele(dirp); dirp = NULL; } - nfsm_reply(NFSX_SRVFH(v3) + NFSX_FATTR(v3) + NFSX_WCCDATA(v3)); - if (v3) { + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_SRVFH(info.v3) + NFSX_FATTR(info.v3) + + NFSX_WCCDATA(info.v3), + &error)); + if (info.v3) { if (!error) { - nfsm_srvpostop_fh(fhp); - nfsm_srvpostop_attr(0, vap); + nfsm_srvpostop_fh(&info, fhp); + nfsm_srvpostop_attr(&info, nfsd, 0, vap); } - nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); + nfsm_srvwcc_data(&info, nfsd, dirfor_ret, &dirfor, + diraft_ret, &diraft); error = 0; } else { - nfsm_srvfhtom(fhp, v3); - nfsm_build(fp, struct nfs_fattr *, NFSX_V2FATTR); - nfsm_srvfillattr(vap, fp); + nfsm_srvfhtom(&info, fhp); + fp = nfsm_build(&info, NFSX_V2FATTR); + nfsm_srvfattr(nfsd, vap, fp); } goto nfsmout; nfsmreply0: - nfsm_reply(0); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, 0, &error)); error = 0; /* fall through */ nfsmout: + info.mreq = NULL; if (dirp) vrele(dirp); nlookup_done(&nd); @@ -1810,25 +1870,20 @@ int nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq) { - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; struct ucred *cred = &nfsd->nd_cr; struct vattr va, dirfor, diraft; struct vattr *vap = &va; u_int32_t *tl; struct nlookupdata nd; - int32_t t1; - caddr_t bpos; int error = 0, len, dirfor_ret = 1, diraft_ret = 1; enum vtype vtyp; - char *cp2; - struct mbuf *mb, *mb2, *mreq; struct vnode *dirp; struct vnode *dvp; struct vnode *vp; nfsfh_t nfh; fhandle_t *fhp; + struct nfsm_info info; nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); nlookup_zero(&nd); @@ -1836,9 +1891,14 @@ nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, dvp = NULL; vp = NULL; + info.mrep = nfsd->nd_mrep; + info.mreq = NULL; + info.md = nfsd->nd_md; + info.dpos = nfsd->nd_dpos; + fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - nfsm_srvnamesiz(len); + NEGREPLYOUT(nfsm_srvmtofh(&info, nfsd, fhp, &error)); + NEGREPLYOUT(len = nfsm_srvnamesiz(&info, &error)); /* * Handle nfs_namei() call. If an error occurs, the nd structure @@ -1847,26 +1907,28 @@ nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, */ error = nfs_namei(&nd, cred, NLC_CREATE, &dvp, &vp, - fhp, len, slp, nam, &md, &dpos, &dirp, + fhp, len, slp, nam, &info.md, &info.dpos, &dirp, td, (nfsd->nd_flag & ND_KERBAUTH), FALSE); if (dirp) dirfor_ret = VOP_GETATTR(dirp, &dirfor); if (error) { - nfsm_reply(NFSX_WCCDATA(1)); - nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_WCCDATA(1), &error)); + nfsm_srvwcc_data(&info, nfsd, dirfor_ret, &dirfor, + diraft_ret, &diraft); error = 0; goto nfsmout; } - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED)); vtyp = nfsv3tov_type(*tl); if (vtyp != VCHR && vtyp != VBLK && vtyp != VSOCK && vtyp != VFIFO) { error = NFSERR_BADTYPE; goto out; } VATTR_NULL(vap); - nfsm_srvsattr(vap); + ERROROUT(nfsm_srvsattr(&info, vap)); if (vtyp == VCHR || vtyp == VBLK) { - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + NULLOUT(tl = nfsm_dissect(&info, 2 * NFSX_UNSIGNED)); vap->va_rmajor = fxdr_unsigned(u_int32_t, *tl++); vap->va_rminor = fxdr_unsigned(u_int32_t, *tl); } @@ -1925,14 +1987,18 @@ out: vrele(dirp); dirp = NULL; } - nfsm_reply(NFSX_SRVFH(1) + NFSX_POSTOPATTR(1) + NFSX_WCCDATA(1)); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_SRVFH(1) + NFSX_POSTOPATTR(1) + + NFSX_WCCDATA(1), &error)); if (!error) { - nfsm_srvpostop_fh(fhp); - nfsm_srvpostop_attr(0, vap); + nfsm_srvpostop_fh(&info, fhp); + nfsm_srvpostop_attr(&info, nfsd, 0, vap); } - nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); + nfsm_srvwcc_data(&info, nfsd, dirfor_ret, &dirfor, + diraft_ret, &diraft); return (0); nfsmout: + *mrq = info.mreq; if (dirp) vrele(dirp); nlookup_done(&nd); @@ -1954,24 +2020,17 @@ int nfsrv_remove(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq) { - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; struct ucred *cred = &nfsd->nd_cr; struct nlookupdata nd; - u_int32_t *tl; - int32_t t1; - caddr_t bpos; int error = 0, len, dirfor_ret = 1, diraft_ret = 1; - int v3 = (nfsd->nd_flag & ND_NFSV3); - char *cp2; - struct mbuf *mb, *mreq; struct vnode *dirp; struct vnode *dvp; struct vnode *vp; struct vattr dirfor, diraft; nfsfh_t nfh; fhandle_t *fhp; + struct nfsm_info info; nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); nlookup_zero(&nd); @@ -1979,15 +2038,21 @@ nfsrv_remove(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, dvp = NULL; vp = NULL; + info.mrep = nfsd->nd_mrep; + info.mreq = NULL; + info.md = nfsd->nd_md; + info.dpos = nfsd->nd_dpos; + info.v3 = (nfsd->nd_flag & ND_NFSV3); + fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - nfsm_srvnamesiz(len); + NEGREPLYOUT(nfsm_srvmtofh(&info, nfsd, fhp, &error)); + NEGREPLYOUT(len = nfsm_srvnamesiz(&info, &error)); error = nfs_namei(&nd, cred, NLC_DELETE, &dvp, &vp, - fhp, len, slp, nam, &md, &dpos, &dirp, + fhp, len, slp, nam, &info.md, &info.dpos, &dirp, td, (nfsd->nd_flag & ND_KERBAUTH), FALSE); if (dirp) { - if (v3) + if (info.v3) dirfor_ret = VOP_GETATTR(dirp, &dirfor); } if (error == 0) { @@ -2015,14 +2080,16 @@ out: dvp = NULL; } } - if (dirp && v3) + if (dirp && info.v3) diraft_ret = VOP_GETATTR(dirp, &diraft); - nfsm_reply(NFSX_WCCDATA(v3)); - if (v3) { - nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, NFSX_WCCDATA(info.v3), &error)); + if (info.v3) { + nfsm_srvwcc_data(&info, nfsd, dirfor_ret, &dirfor, + diraft_ret, &diraft); error = 0; } nfsmout: + *mrq = info.mreq; nlookup_done(&nd); if (dirp) vrele(dirp); @@ -2044,18 +2111,10 @@ int nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq) { - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; struct ucred *cred = &nfsd->nd_cr; - u_int32_t *tl; - int32_t t1; - caddr_t bpos; int error = 0, len, len2, fdirfor_ret = 1, fdiraft_ret = 1; int tdirfor_ret = 1, tdiraft_ret = 1; - int v3 = (nfsd->nd_flag & ND_NFSV3); - char *cp2; - struct mbuf *mb, *mreq; struct nlookupdata fromnd, tond; struct vnode *fvp, *fdirp, *fdvp; struct vnode *tvp, *tdirp, *tdvp; @@ -2064,6 +2123,13 @@ nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, nfsfh_t fnfh, tnfh; fhandle_t *ffhp, *tfhp; uid_t saved_uid; + struct nfsm_info info; + + info.mrep = nfsd->nd_mrep; + info.mreq = NULL; + info.md = nfsd->nd_md; + info.dpos = nfsd->nd_dpos; + info.v3 = (nfsd->nd_flag & ND_NFSV3); nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); #ifndef nolint @@ -2081,8 +2147,9 @@ nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, fdirp = NULL; tdirp = NULL; - nfsm_srvmtofh(ffhp); - nfsm_srvnamesiz(len); + NEGREPLYOUT(nfsm_srvmtofh(&info, nfsd, ffhp, &error)); + NEGREPLYOUT(len = nfsm_srvnamesiz(&info, &error)); + /* * Remember our original uid so that we can reset cr_uid before * the second nfs_namei() call, in case it is remapped. @@ -2090,16 +2157,19 @@ nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, saved_uid = cred->cr_uid; error = nfs_namei(&fromnd, cred, NLC_RENAME_SRC, NULL, NULL, - ffhp, len, slp, nam, &md, &dpos, &fdirp, + ffhp, len, slp, nam, &info.md, &info.dpos, &fdirp, td, (nfsd->nd_flag & ND_KERBAUTH), FALSE); if (fdirp) { - if (v3) + if (info.v3) fdirfor_ret = VOP_GETATTR(fdirp, &fdirfor); } if (error) { - nfsm_reply(2 * NFSX_WCCDATA(v3)); - nfsm_srvwcc_data(fdirfor_ret, &fdirfor, fdiraft_ret, &fdiraft); - nfsm_srvwcc_data(tdirfor_ret, &tdirfor, tdiraft_ret, &tdiraft); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + 2 * NFSX_WCCDATA(info.v3), &error)); + nfsm_srvwcc_data(&info, nfsd, fdirfor_ret, &fdirfor, + fdiraft_ret, &fdiraft); + nfsm_srvwcc_data(&info, nfsd, tdirfor_ret, &tdirfor, + tdiraft_ret, &tdiraft); error = 0; goto nfsmout; } @@ -2111,15 +2181,15 @@ nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, KKASSERT(fromnd.nl_flags & NLC_NCPISLOCKED); cache_unlock(&fromnd.nl_nch); fromnd.nl_flags &= ~NLC_NCPISLOCKED; - nfsm_srvmtofh(tfhp); - nfsm_strsiz(len2, NFS_MAXNAMLEN); + NEGREPLYOUT(nfsm_srvmtofh(&info, nfsd, tfhp, &error)); + NEGATIVEOUT(len2 = nfsm_strsiz(&info, NFS_MAXNAMLEN)); cred->cr_uid = saved_uid; error = nfs_namei(&tond, cred, NLC_RENAME_DST, NULL, NULL, - tfhp, len2, slp, nam, &md, &dpos, &tdirp, + tfhp, len2, slp, nam, &info.md, &info.dpos, &tdirp, td, (nfsd->nd_flag & ND_KERBAUTH), FALSE); if (tdirp) { - if (v3) + if (info.v3) tdirfor_ret = VOP_GETATTR(tdirp, &tdirfor); } if (error) @@ -2165,20 +2235,20 @@ nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, if (tvp != NULL) { if (fvp->v_type == VDIR && tvp->v_type != VDIR) { - if (v3) + if (info.v3) error = EEXIST; else error = EISDIR; goto out; } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) { - if (v3) + if (info.v3) error = EEXIST; else error = ENOTDIR; goto out; } if (tvp->v_type == VDIR && (tond.nl_nch.ncp->nc_flag & NCF_ISMOUNTPT)) { - if (v3) + if (info.v3) error = EXDEV; else error = ENOTEMPTY; @@ -2186,21 +2256,21 @@ nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, } } if (fvp->v_type == VDIR && (fromnd.nl_nch.ncp->nc_flag & NCF_ISMOUNTPT)) { - if (v3) + if (info.v3) error = EXDEV; else error = ENOTEMPTY; goto out; } if (fromnd.nl_nch.mount != tond.nl_nch.mount) { - if (v3) + if (info.v3) error = EXDEV; else error = ENOTEMPTY; goto out; } if (fromnd.nl_nch.ncp == tond.nl_nch.ncp->nc_parent) { - if (v3) + if (info.v3) error = EINVAL; else error = ENOTEMPTY; @@ -2247,15 +2317,19 @@ out1: fdiraft_ret = VOP_GETATTR(fdirp, &fdiraft); if (tdirp) tdiraft_ret = VOP_GETATTR(tdirp, &tdiraft); - nfsm_reply(2 * NFSX_WCCDATA(v3)); - if (v3) { - nfsm_srvwcc_data(fdirfor_ret, &fdirfor, fdiraft_ret, &fdiraft); - nfsm_srvwcc_data(tdirfor_ret, &tdirfor, tdiraft_ret, &tdiraft); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + 2 * NFSX_WCCDATA(info.v3), &error)); + if (info.v3) { + nfsm_srvwcc_data(&info, nfsd, fdirfor_ret, &fdirfor, + fdiraft_ret, &fdiraft); + nfsm_srvwcc_data(&info, nfsd, tdirfor_ret, &tdirfor, + tdiraft_ret, &tdiraft); } error = 0; /* fall through */ nfsmout: + *mrq = info.mreq; if (tdirp) vrele(tdirp); nlookup_done(&tond); @@ -2272,18 +2346,11 @@ int nfsrv_link(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq) { - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; struct ucred *cred = &nfsd->nd_cr; struct nlookupdata nd; - u_int32_t *tl; - int32_t t1; - caddr_t bpos; int error = 0, rdonly, len, dirfor_ret = 1, diraft_ret = 1; - int getret = 1, v3 = (nfsd->nd_flag & ND_NFSV3); - char *cp2; - struct mbuf *mb, *mreq; + int getret = 1; struct vnode *dirp; struct vnode *dvp; struct vnode *vp; @@ -2293,6 +2360,13 @@ nfsrv_link(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct vattr dirfor, diraft, at; nfsfh_t nfh, dnfh; fhandle_t *fhp, *dfhp; + struct nfsm_info info; + + info.mrep = nfsd->nd_mrep; + info.mreq = NULL; + info.md = nfsd->nd_md; + info.dpos = nfsd->nd_dpos; + info.v3 = (nfsd->nd_flag & ND_NFSV3); nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); nlookup_zero(&nd); @@ -2301,16 +2375,20 @@ nfsrv_link(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, fhp = &nfh.fh_generic; dfhp = &dnfh.fh_generic; - nfsm_srvmtofh(fhp); - nfsm_srvmtofh(dfhp); - nfsm_srvnamesiz(len); + NEGREPLYOUT(nfsm_srvmtofh(&info, nfsd, fhp, &error)); + NEGREPLYOUT(nfsm_srvmtofh(&info, nfsd, dfhp, &error)); + NEGREPLYOUT(len = nfsm_srvnamesiz(&info, &error)); error = nfsrv_fhtovp(fhp, FALSE, &xmp, &xp, cred, slp, nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (error) { - nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3)); - nfsm_srvpostop_attr(getret, &at); - nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_POSTOPATTR(info.v3) + + NFSX_WCCDATA(info.v3), + &error)); + nfsm_srvpostop_attr(&info, nfsd, getret, &at); + nfsm_srvwcc_data(&info, nfsd, dirfor_ret, &dirfor, + diraft_ret, &diraft); xp = NULL; error = 0; goto nfsmout; @@ -2321,10 +2399,10 @@ nfsrv_link(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, } error = nfs_namei(&nd, cred, NLC_CREATE, &dvp, &vp, - dfhp, len, slp, nam, &md, &dpos, &dirp, + dfhp, len, slp, nam, &info.md, &info.dpos, &dirp, td, (nfsd->nd_flag & ND_KERBAUTH), FALSE); if (dirp) { - if (v3) + if (info.v3) dirfor_ret = VOP_GETATTR(dirp, &dirfor); } if (error) @@ -2346,19 +2424,23 @@ out: /* fall through */ out1: - if (v3) + if (info.v3) getret = VOP_GETATTR(xp, &at); if (dirp) diraft_ret = VOP_GETATTR(dirp, &diraft); - nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3)); - if (v3) { - nfsm_srvpostop_attr(getret, &at); - nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_POSTOPATTR(info.v3) + NFSX_WCCDATA(info.v3), + &error)); + if (info.v3) { + nfsm_srvpostop_attr(&info, nfsd, getret, &at); + nfsm_srvwcc_data(&info, nfsd, dirfor_ret, &dirfor, + diraft_ret, &diraft); error = 0; } /* fall through */ nfsmout: + *mrq = info.mreq; nlookup_done(&nd); if (dirp) vrele(dirp); @@ -2382,27 +2464,22 @@ int nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq) { - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; struct ucred *cred = &nfsd->nd_cr; struct vattr va, dirfor, diraft; struct nlookupdata nd; struct vattr *vap = &va; - u_int32_t *tl; - int32_t t1; struct nfsv2_sattr *sp; - char *bpos, *pathcp = NULL, *cp2; + char *pathcp = NULL; struct uio io; struct iovec iv; int error = 0, len, len2, dirfor_ret = 1, diraft_ret = 1; - int v3 = (nfsd->nd_flag & ND_NFSV3); - struct mbuf *mb, *mreq, *mb2; struct vnode *dirp; struct vnode *vp; struct vnode *dvp; nfsfh_t nfh; fhandle_t *fhp; + struct nfsm_info info; nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); nlookup_zero(&nd); @@ -2410,24 +2487,31 @@ nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, dvp = NULL; vp = NULL; + info.mrep = nfsd->nd_mrep; + info.mreq = NULL; + info.md = nfsd->nd_md; + info.dpos = nfsd->nd_dpos; + info.v3 = (nfsd->nd_flag & ND_NFSV3); + fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - nfsm_srvnamesiz(len); + NEGREPLYOUT(nfsm_srvmtofh(&info, nfsd, fhp, &error)); + NEGREPLYOUT(len = nfsm_srvnamesiz(&info, &error)); error = nfs_namei(&nd, cred, NLC_CREATE, &dvp, &vp, - fhp, len, slp, nam, &md, &dpos, &dirp, + fhp, len, slp, nam, &info.md, &info.dpos, &dirp, td, (nfsd->nd_flag & ND_KERBAUTH), FALSE); if (dirp) { - if (v3) + if (info.v3) dirfor_ret = VOP_GETATTR(dirp, &dirfor); } if (error) goto out; VATTR_NULL(vap); - if (v3) - nfsm_srvsattr(vap); - nfsm_strsiz(len2, NFS_MAXPATHLEN); + if (info.v3) { + ERROROUT(nfsm_srvsattr(&info, vap)); + } + NEGATIVEOUT(len2 = nfsm_strsiz(&info, NFS_MAXPATHLEN)); MALLOC(pathcp, caddr_t, len2 + 1, M_TEMP, M_WAITOK); iv.iov_base = pathcp; iv.iov_len = len2; @@ -2438,9 +2522,9 @@ nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, io.uio_segflg = UIO_SYSSPACE; io.uio_rw = UIO_READ; io.uio_td = NULL; - nfsm_mtouio(&io, len2); - if (!v3) { - nfsm_dissect(sp, struct nfsv2_sattr *, NFSX_V2SATTR); + ERROROUT(nfsm_mtouio(&info, &io, len2)); + if (info.v3 == 0) { + NULLOUT(sp = nfsm_dissect(&info, NFSX_V2SATTR)); vap->va_mode = nfstov_mode(sp->sa_mode); } *(pathcp + len2) = '\0'; @@ -2483,18 +2567,23 @@ out: vrele(dirp); dirp = NULL; } - nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3)); - if (v3) { + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_SRVFH(info.v3) + NFSX_POSTOPATTR(info.v3) + + NFSX_WCCDATA(info.v3), + &error)); + if (info.v3) { if (!error) { - nfsm_srvpostop_fh(fhp); - nfsm_srvpostop_attr(0, vap); + nfsm_srvpostop_fh(&info, fhp); + nfsm_srvpostop_attr(&info, nfsd, 0, vap); } - nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); + nfsm_srvwcc_data(&info, nfsd, dirfor_ret, &dirfor, + diraft_ret, &diraft); } error = 0; /* fall through */ nfsmout: + *mrq = info.mreq; nlookup_done(&nd); if (vp) vput(vp); @@ -2512,27 +2601,20 @@ int nfsrv_mkdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq) { - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; struct ucred *cred = &nfsd->nd_cr; struct vattr va, dirfor, diraft; struct vattr *vap = &va; struct nfs_fattr *fp; struct nlookupdata nd; - caddr_t cp; u_int32_t *tl; - int32_t t1; - caddr_t bpos; int error = 0, len, dirfor_ret = 1, diraft_ret = 1; - int v3 = (nfsd->nd_flag & ND_NFSV3); - char *cp2; - struct mbuf *mb, *mb2, *mreq; struct vnode *dirp; struct vnode *dvp; struct vnode *vp; nfsfh_t nfh; fhandle_t *fhp; + struct nfsm_info info; nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); nlookup_zero(&nd); @@ -2540,28 +2622,36 @@ nfsrv_mkdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, dvp = NULL; vp = NULL; + info.dpos = nfsd->nd_dpos; + info.mrep = nfsd->nd_mrep; + info.mreq = NULL; + info.md = nfsd->nd_md; + info.v3 = (nfsd->nd_flag & ND_NFSV3); + fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - nfsm_srvnamesiz(len); + NEGREPLYOUT(nfsm_srvmtofh(&info, nfsd, fhp, &error)); + NEGREPLYOUT(len = nfsm_srvnamesiz(&info, &error)); error = nfs_namei(&nd, cred, NLC_CREATE, &dvp, &vp, - fhp, len, slp, nam, &md, &dpos, &dirp, + fhp, len, slp, nam, &info.md, &info.dpos, &dirp, td, (nfsd->nd_flag & ND_KERBAUTH), FALSE); if (dirp) { - if (v3) + if (info.v3) dirfor_ret = VOP_GETATTR(dirp, &dirfor); } if (error) { - nfsm_reply(NFSX_WCCDATA(v3)); - nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_WCCDATA(info.v3), &error)); + nfsm_srvwcc_data(&info, nfsd, dirfor_ret, &dirfor, + diraft_ret, &diraft); error = 0; goto nfsmout; } VATTR_NULL(vap); - if (v3) { - nfsm_srvsattr(vap); + if (info.v3) { + ERROROUT(nfsm_srvsattr(&info, vap)); } else { - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED)); vap->va_mode = nfstov_mode(*tl++); } @@ -2597,22 +2687,27 @@ nfsrv_mkdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, out: if (dirp) diraft_ret = VOP_GETATTR(dirp, &diraft); - nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3)); - if (v3) { + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_SRVFH(info.v3) + NFSX_POSTOPATTR(info.v3) + + NFSX_WCCDATA(info.v3), + &error)); + if (info.v3) { if (!error) { - nfsm_srvpostop_fh(fhp); - nfsm_srvpostop_attr(0, vap); + nfsm_srvpostop_fh(&info, fhp); + nfsm_srvpostop_attr(&info, nfsd, 0, vap); } - nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); + nfsm_srvwcc_data(&info, nfsd, dirfor_ret, &dirfor, + diraft_ret, &diraft); } else { - nfsm_srvfhtom(fhp, v3); - nfsm_build(fp, struct nfs_fattr *, NFSX_V2FATTR); - nfsm_srvfillattr(vap, fp); + nfsm_srvfhtom(&info, fhp); + fp = nfsm_build(&info, NFSX_V2FATTR); + nfsm_srvfattr(nfsd, vap, fp); } error = 0; /* fall through */ nfsmout: + *mrq = info.mreq; nlookup_done(&nd); if (dirp) vrele(dirp); @@ -2634,17 +2729,9 @@ int nfsrv_rmdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq) { - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; struct ucred *cred = &nfsd->nd_cr; - u_int32_t *tl; - int32_t t1; - caddr_t bpos; int error = 0, len, dirfor_ret = 1, diraft_ret = 1; - int v3 = (nfsd->nd_flag & ND_NFSV3); - char *cp2; - struct mbuf *mb, *mreq; struct vnode *dirp; struct vnode *dvp; struct vnode *vp; @@ -2652,6 +2739,7 @@ nfsrv_rmdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, nfsfh_t nfh; fhandle_t *fhp; struct nlookupdata nd; + struct nfsm_info info; nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); nlookup_zero(&nd); @@ -2659,20 +2747,28 @@ nfsrv_rmdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, dvp = NULL; vp = NULL; + info.mrep = nfsd->nd_mrep; + info.mreq = NULL; + info.md = nfsd->nd_md; + info.dpos = nfsd->nd_dpos; + info.v3 = (nfsd->nd_flag & ND_NFSV3); + fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - nfsm_srvnamesiz(len); + NEGREPLYOUT(nfsm_srvmtofh(&info, nfsd, fhp, &error)); + NEGREPLYOUT(len = nfsm_srvnamesiz(&info, &error)); error = nfs_namei(&nd, cred, NLC_DELETE, &dvp, &vp, - fhp, len, slp, nam, &md, &dpos, &dirp, + fhp, len, slp, nam, &info.md, &info.dpos, &dirp, td, (nfsd->nd_flag & ND_KERBAUTH), FALSE); if (dirp) { - if (v3) + if (info.v3) dirfor_ret = VOP_GETATTR(dirp, &dirfor); } if (error) { - nfsm_reply(NFSX_WCCDATA(v3)); - nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_WCCDATA(info.v3), &error)); + nfsm_srvwcc_data(&info, nfsd, dirfor_ret, &dirfor, + diraft_ret, &diraft); error = 0; goto nfsmout; } @@ -2704,14 +2800,16 @@ out: if (dirp) diraft_ret = VOP_GETATTR(dirp, &diraft); - nfsm_reply(NFSX_WCCDATA(v3)); - if (v3) { - nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, NFSX_WCCDATA(info.v3), &error)); + if (info.v3) { + nfsm_srvwcc_data(&info, nfsd, dirfor_ret, &dirfor, + diraft_ret, &diraft); error = 0; } /* fall through */ nfsmout: + *mrq = info.mreq; if (dvp) { if (dvp == vp) vrele(dvp); @@ -2768,18 +2866,14 @@ int nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq) { - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; struct ucred *cred = &nfsd->nd_cr; char *bp, *be; struct dirent *dp; caddr_t cp; u_int32_t *tl; - int32_t t1; - caddr_t bpos; - struct mbuf *mb, *mb2, *mreq, *mp1, *mp2; - char *cpos, *cend, *cp2, *rbuf; + struct mbuf *mp1, *mp2; + char *cpos, *cend, *rbuf; struct vnode *vp = NULL; struct mount *mp = NULL; struct vattr at; @@ -2789,21 +2883,27 @@ nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct iovec iv; int len, nlen, rem, xfer, tsiz, i, error = 0, getret = 1; int siz, cnt, fullsiz, eofflag, rdonly, ncookies; - int v3 = (nfsd->nd_flag & ND_NFSV3); u_quad_t off, toff, verf; off_t *cookies = NULL, *cookiep; + struct nfsm_info info; + + info.mrep = nfsd->nd_mrep; + info.mreq = NULL; + info.md = nfsd->nd_md; + info.dpos = nfsd->nd_dpos; + info.v3 = (nfsd->nd_flag & ND_NFSV3); nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - if (v3) { - nfsm_dissect(tl, u_int32_t *, 5 * NFSX_UNSIGNED); + NEGREPLYOUT(nfsm_srvmtofh(&info, nfsd, fhp, &error)); + if (info.v3) { + NULLOUT(tl = nfsm_dissect(&info, 5 * NFSX_UNSIGNED)); toff = fxdr_hyper(tl); tl += 2; verf = fxdr_hyper(tl); tl += 2; } else { - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + NULLOUT(tl = nfsm_dissect(&info, 2 * NFSX_UNSIGNED)); toff = fxdr_unsigned(u_quad_t, *tl++); verf = 0; /* shut up gcc */ } @@ -2824,8 +2924,8 @@ nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, vp = NULL; } if (error) { - nfsm_reply(NFSX_UNSIGNED); - nfsm_srvpostop_attr(getret, &at); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, NFSX_UNSIGNED, &error)); + nfsm_srvpostop_attr(&info, nfsd, getret, &at); error = 0; goto nfsmout; } @@ -2834,7 +2934,7 @@ nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, * Obtain lock on vnode for this section of the code */ - if (v3) { + if (info.v3) { error = getret = VOP_GETATTR(vp, &at); #if 0 /* @@ -2849,8 +2949,9 @@ nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, if (error) { vput(vp); vp = NULL; - nfsm_reply(NFSX_POSTOPATTR(v3)); - nfsm_srvpostop_attr(getret, &at); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_POSTOPATTR(info.v3), &error)); + nfsm_srvpostop_attr(&info, nfsd, getret, &at); error = 0; goto nfsmout; } @@ -2879,7 +2980,7 @@ again: off = (off_t)io.uio_offset; if (!cookies && !error) error = NFSERR_PERM; - if (v3) { + if (info.v3) { getret = VOP_GETATTR(vp, &at); if (!error) error = getret; @@ -2890,8 +2991,9 @@ again: kfree((caddr_t)rbuf, M_TEMP); if (cookies) kfree((caddr_t)cookies, M_TEMP); - nfsm_reply(NFSX_POSTOPATTR(v3)); - nfsm_srvpostop_attr(getret, &at); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_POSTOPATTR(info.v3), &error)); + nfsm_srvpostop_attr(&info, nfsd, getret, &at); error = 0; goto nfsmout; } @@ -2905,15 +3007,18 @@ again: if (siz == 0) { vrele(vp); vp = NULL; - nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_COOKIEVERF(v3) + - 2 * NFSX_UNSIGNED); - if (v3) { - nfsm_srvpostop_attr(getret, &at); - nfsm_build(tl, u_int32_t *, 4 * NFSX_UNSIGNED); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_POSTOPATTR(info.v3) + + NFSX_COOKIEVERF(info.v3) + + 2 * NFSX_UNSIGNED, + &error)); + if (info.v3) { + nfsm_srvpostop_attr(&info, nfsd, getret, &at); + tl = nfsm_build(&info, 4 * NFSX_UNSIGNED); txdr_hyper(at.va_filerev, tl); tl += 2; } else - nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + tl = nfsm_build(&info, 2 * NFSX_UNSIGNED); *tl++ = nfs_false; *tl = nfs_true; FREE((caddr_t)rbuf, M_TEMP); @@ -2953,14 +3058,17 @@ again: } len = 3 * NFSX_UNSIGNED; /* paranoia, probably can be 0 */ - nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_COOKIEVERF(v3) + siz); - if (v3) { - nfsm_srvpostop_attr(getret, &at); - nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_POSTOPATTR(info.v3) + + NFSX_COOKIEVERF(info.v3) + siz, + &error)); + if (info.v3) { + nfsm_srvpostop_attr(&info, nfsd, getret, &at); + tl = nfsm_build(&info, 2 * NFSX_UNSIGNED); txdr_hyper(at.va_filerev, tl); } - mp1 = mp2 = mb; - bp = bpos; + mp1 = mp2 = info.mb; + bp = info.bpos; be = bp + M_TRAILINGSPACE(mp1); /* Loop through the records and build reply */ @@ -2969,7 +3077,7 @@ again: nlen = dp->d_namlen; rem = nfsm_rndup(nlen) - nlen; len += (4 * NFSX_UNSIGNED + nlen + rem); - if (v3) + if (info.v3) len += 2 * NFSX_UNSIGNED; if (len > cnt) { eofflag = 0; @@ -2979,18 +3087,18 @@ again: * Build the directory record xdr from * the dirent entry. */ - nfsm_clget(mp1, mp2, mb, bp, be, tl); + tl = nfsm_clget(&info, mp1, mp2, bp, be); *tl = nfs_true; bp += NFSX_UNSIGNED; - if (v3) { - nfsm_clget(mp1, mp2, mb, bp, be, tl); + if (info.v3) { + tl = nfsm_clget(&info, mp1, mp2, bp, be); *tl = 0; bp += NFSX_UNSIGNED; } - nfsm_clget(mp1, mp2, mb, bp, be, tl); + tl = nfsm_clget(&info, mp1, mp2, bp, be); *tl = txdr_unsigned(dp->d_ino); bp += NFSX_UNSIGNED; - nfsm_clget(mp1, mp2, mb, bp, be, tl); + tl = nfsm_clget(&info, mp1, mp2, bp, be); *tl = txdr_unsigned(nlen); bp += NFSX_UNSIGNED; @@ -2998,7 +3106,7 @@ again: xfer = nlen; cp = dp->d_name; while (xfer > 0) { - nfsm_clget(mp1, mp2, mb, bp, be, tl); + tl = nfsm_clget(&info, mp1, mp2, bp, be); if ((bp+xfer) > be) tsiz = be-bp; else @@ -3012,13 +3120,13 @@ again: /* And null pad to a int32_t boundary */ for (i = 0; i < rem; i++) *bp++ = '\0'; - nfsm_clget(mp1, mp2, mb, bp, be, tl); + tl = nfsm_clget(&info, mp1, mp2, bp, be); /* Finish off the record */ - if (v3) { + if (info.v3) { *tl = txdr_unsigned(*cookiep >> 32); bp += NFSX_UNSIGNED; - nfsm_clget(mp1, mp2, mb, bp, be, tl); + tl = nfsm_clget(&info, mp1, mp2, bp, be); } *tl = txdr_unsigned(*cookiep); bp += NFSX_UNSIGNED; @@ -3030,24 +3138,25 @@ again: } vrele(vp); vp = NULL; - nfsm_clget(mp1, mp2, mb, bp, be, tl); + tl = nfsm_clget(&info, mp1, mp2, bp, be); *tl = nfs_false; bp += NFSX_UNSIGNED; - nfsm_clget(mp1, mp2, mb, bp, be, tl); + tl = nfsm_clget(&info, mp1, mp2, bp, be); if (eofflag) *tl = nfs_true; else *tl = nfs_false; bp += NFSX_UNSIGNED; - if (mp1 != mb) { + if (mp1 != info.mb) { if (bp < be) mp1->m_len = bp - mtod(mp1, caddr_t); } else - mp1->m_len += bp - bpos; + mp1->m_len += bp - info.bpos; FREE((caddr_t)rbuf, M_TEMP); FREE((caddr_t)cookies, M_TEMP); nfsmout: + *mrq = info.mreq; if (vp) vrele(vp); return(error); @@ -3057,18 +3166,14 @@ int nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq) { - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; struct ucred *cred = &nfsd->nd_cr; char *bp, *be; struct dirent *dp; caddr_t cp; u_int32_t *tl; - int32_t t1; - caddr_t bpos; - struct mbuf *mb, *mb2, *mreq, *mp1, *mp2; - char *cpos, *cend, *cp2, *rbuf; + struct mbuf *mp1, *mp2; + char *cpos, *cend, *rbuf; struct vnode *vp = NULL, *nvp; struct mount *mp = NULL; struct flrep fl; @@ -3082,11 +3187,17 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, int siz, cnt, fullsiz, eofflag, rdonly, dirlen, ncookies; u_quad_t off, toff, verf; off_t *cookies = NULL, *cookiep; /* needs to be int64_t or off_t */ + struct nfsm_info info; + + info.mrep = nfsd->nd_mrep; + info.mreq = NULL; + info.md = nfsd->nd_md; + info.dpos = nfsd->nd_dpos; nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - nfsm_dissect(tl, u_int32_t *, 6 * NFSX_UNSIGNED); + NEGREPLYOUT(nfsm_srvmtofh(&info, nfsd, fhp, &error)); + NULLOUT(tl = nfsm_dissect(&info, 6 * NFSX_UNSIGNED)); toff = fxdr_hyper(tl); tl += 2; verf = fxdr_hyper(tl); @@ -3109,8 +3220,8 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, vp = NULL; } if (error) { - nfsm_reply(NFSX_UNSIGNED); - nfsm_srvpostop_attr(getret, &at); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, NFSX_UNSIGNED, &error)); + nfsm_srvpostop_attr(&info, nfsd, getret, &at); error = 0; goto nfsmout; } @@ -3128,8 +3239,9 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, if (error) { vput(vp); vp = NULL; - nfsm_reply(NFSX_V3POSTOPATTR); - nfsm_srvpostop_attr(getret, &at); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_V3POSTOPATTR, &error)); + nfsm_srvpostop_attr(&info, nfsd, getret, &at); error = 0; goto nfsmout; } @@ -3163,8 +3275,9 @@ again: if (cookies) kfree((caddr_t)cookies, M_TEMP); kfree((caddr_t)rbuf, M_TEMP); - nfsm_reply(NFSX_V3POSTOPATTR); - nfsm_srvpostop_attr(getret, &at); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_V3POSTOPATTR, &error)); + nfsm_srvpostop_attr(&info, nfsd, getret, &at); error = 0; goto nfsmout; } @@ -3178,10 +3291,13 @@ again: if (siz == 0) { vrele(vp); vp = NULL; - nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3COOKIEVERF + - 2 * NFSX_UNSIGNED); - nfsm_srvpostop_attr(getret, &at); - nfsm_build(tl, u_int32_t *, 4 * NFSX_UNSIGNED); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_V3POSTOPATTR + + NFSX_V3COOKIEVERF + + 2 * NFSX_UNSIGNED, + &error)); + nfsm_srvpostop_attr(&info, nfsd, getret, &at); + tl = nfsm_build(&info, 4 * NFSX_UNSIGNED); txdr_hyper(at.va_filerev, tl); tl += 2; *tl++ = nfs_false; @@ -3232,8 +3348,9 @@ again: vp = NULL; kfree((caddr_t)cookies, M_TEMP); kfree((caddr_t)rbuf, M_TEMP); - nfsm_reply(NFSX_V3POSTOPATTR); - nfsm_srvpostop_attr(getret, &at); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_V3POSTOPATTR, &error)); + nfsm_srvpostop_attr(&info, nfsd, getret, &at); error = 0; goto nfsmout; } @@ -3242,13 +3359,14 @@ again: nvp = NULL; } - dirlen = len = NFSX_V3POSTOPATTR + NFSX_V3COOKIEVERF + 2 * NFSX_UNSIGNED; - nfsm_reply(cnt); - nfsm_srvpostop_attr(getret, &at); - nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + dirlen = len = NFSX_V3POSTOPATTR + NFSX_V3COOKIEVERF + + 2 * NFSX_UNSIGNED; + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, cnt, &error)); + nfsm_srvpostop_attr(&info, nfsd, getret, &at); + tl = nfsm_build(&info, 2 * NFSX_UNSIGNED); txdr_hyper(at.va_filerev, tl); - mp1 = mp2 = mb; - bp = bpos; + mp1 = mp2 = info.mb; + bp = info.bpos; be = bp + M_TRAILINGSPACE(mp1); /* Loop through the records and build reply */ @@ -3297,23 +3415,23 @@ again: * the dirent entry. */ fp = (struct nfs_fattr *)&fl.fl_fattr; - nfsm_srvfillattr(vap, fp); + nfsm_srvfattr(nfsd, vap, fp); fl.fl_fhsize = txdr_unsigned(NFSX_V3FH); fl.fl_fhok = nfs_true; fl.fl_postopok = nfs_true; fl.fl_off.nfsuquad[0] = txdr_unsigned(*cookiep >> 32); fl.fl_off.nfsuquad[1] = txdr_unsigned(*cookiep); - nfsm_clget(mp1, mp2, mb, bp, be, tl); + tl = nfsm_clget(&info, mp1, mp2, bp, be); *tl = nfs_true; bp += NFSX_UNSIGNED; - nfsm_clget(mp1, mp2, mb, bp, be, tl); + tl = nfsm_clget(&info, mp1, mp2, bp, be); *tl = 0; bp += NFSX_UNSIGNED; - nfsm_clget(mp1, mp2, mb, bp, be, tl); + tl = nfsm_clget(&info, mp1, mp2, bp, be); *tl = txdr_unsigned(dp->d_ino); bp += NFSX_UNSIGNED; - nfsm_clget(mp1, mp2, mb, bp, be, tl); + tl = nfsm_clget(&info, mp1, mp2, bp, be); *tl = txdr_unsigned(nlen); bp += NFSX_UNSIGNED; @@ -3321,7 +3439,7 @@ again: xfer = nlen; cp = dp->d_name; while (xfer > 0) { - nfsm_clget(mp1, mp2, mb, bp, be, tl); + tl = nfsm_clget(&info, mp1, mp2, bp, be); if ((bp + xfer) > be) tsiz = be - bp; else @@ -3342,7 +3460,7 @@ again: xfer = sizeof (struct flrep); cp = (caddr_t)&fl; while (xfer > 0) { - nfsm_clget(mp1, mp2, mb, bp, be, tl); + tl = nfsm_clget(&info, mp1, mp2, bp, be); if ((bp + xfer) > be) tsiz = be - bp; else @@ -3362,23 +3480,24 @@ invalid: } vrele(vp); vp = NULL; - nfsm_clget(mp1, mp2, mb, bp, be, tl); + tl = nfsm_clget(&info, mp1, mp2, bp, be); *tl = nfs_false; bp += NFSX_UNSIGNED; - nfsm_clget(mp1, mp2, mb, bp, be, tl); + tl = nfsm_clget(&info, mp1, mp2, bp, be); if (eofflag) *tl = nfs_true; else *tl = nfs_false; bp += NFSX_UNSIGNED; - if (mp1 != mb) { + if (mp1 != info.mb) { if (bp < be) mp1->m_len = bp - mtod(mp1, caddr_t); } else - mp1->m_len += bp - bpos; + mp1->m_len += bp - info.bpos; FREE((caddr_t)cookies, M_TEMP); FREE((caddr_t)rbuf, M_TEMP); nfsmout: + *mrq = info.mreq; if (vp) vrele(vp); return(error); @@ -3391,9 +3510,7 @@ int nfsrv_commit(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq) { - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; struct ucred *cred = &nfsd->nd_cr; struct vattr bfor, aft; struct vnode *vp = NULL; @@ -3401,17 +3518,19 @@ nfsrv_commit(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, nfsfh_t nfh; fhandle_t *fhp; u_int32_t *tl; - int32_t t1; - caddr_t bpos; int error = 0, rdonly, for_ret = 1, aft_ret = 1, cnt; - char *cp2; - struct mbuf *mb, *mb2, *mreq; u_quad_t off; + struct nfsm_info info; + + info.mrep = nfsd->nd_mrep; + info.mreq = NULL; + info.md = nfsd->nd_md; + info.dpos = nfsd->nd_dpos; nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED); + NEGREPLYOUT(nfsm_srvmtofh(&info, nfsd, fhp, &error)); + NULLOUT(tl = nfsm_dissect(&info, 3 * NFSX_UNSIGNED)); /* * XXX At this time VOP_FSYNC() does not accept offset and byte @@ -3423,8 +3542,10 @@ nfsrv_commit(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, error = nfsrv_fhtovp(fhp, 1, &mp, &vp, cred, slp, nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (error) { - nfsm_reply(2 * NFSX_UNSIGNED); - nfsm_srvwcc_data(for_ret, &bfor, aft_ret, &aft); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + 2 * NFSX_UNSIGNED, &error)); + nfsm_srvwcc_data(&info, nfsd, for_ret, &bfor, + aft_ret, &aft); error = 0; goto nfsmout; } @@ -3503,10 +3624,13 @@ nfsrv_commit(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, aft_ret = VOP_GETATTR(vp, &aft); vput(vp); vp = NULL; - nfsm_reply(NFSX_V3WCCDATA + NFSX_V3WRITEVERF); - nfsm_srvwcc_data(for_ret, &bfor, aft_ret, &aft); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_V3WCCDATA + NFSX_V3WRITEVERF, + &error)); + nfsm_srvwcc_data(&info, nfsd, for_ret, &bfor, + aft_ret, &aft); if (!error) { - nfsm_build(tl, u_int32_t *, NFSX_V3WRITEVERF); + tl = nfsm_build(&info, NFSX_V3WRITEVERF); if (nfsver.tv_sec == 0) nfsver = boottime; *tl++ = txdr_unsigned(nfsver.tv_sec); @@ -3515,6 +3639,7 @@ nfsrv_commit(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, error = 0; } nfsmout: + *mrq = info.mreq; if (vp) vput(vp); return(error); @@ -3527,19 +3652,11 @@ int nfsrv_statfs(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq) { - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; struct ucred *cred = &nfsd->nd_cr; struct statfs *sf; struct nfs_statfs *sfp; - u_int32_t *tl; - int32_t t1; - caddr_t bpos; int error = 0, rdonly, getret = 1; - int v3 = (nfsd->nd_flag & ND_NFSV3); - char *cp2; - struct mbuf *mb, *mb2, *mreq; struct vnode *vp = NULL; struct mount *mp = NULL; struct vattr at; @@ -3547,15 +3664,22 @@ nfsrv_statfs(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, fhandle_t *fhp; struct statfs statfs; u_quad_t tval; + struct nfsm_info info; + + info.mrep = nfsd->nd_mrep; + info.mreq = NULL; + info.md = nfsd->nd_md; + info.dpos = nfsd->nd_dpos; + info.v3 = (nfsd->nd_flag & ND_NFSV3); nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); + NEGREPLYOUT(nfsm_srvmtofh(&info, nfsd, fhp, &error)); error = nfsrv_fhtovp(fhp, 1, &mp, &vp, cred, slp, nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (error) { - nfsm_reply(NFSX_UNSIGNED); - nfsm_srvpostop_attr(getret, &at); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, NFSX_UNSIGNED, &error)); + nfsm_srvpostop_attr(&info, nfsd, getret, &at); error = 0; goto nfsmout; } @@ -3564,15 +3688,17 @@ nfsrv_statfs(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, getret = VOP_GETATTR(vp, &at); vput(vp); vp = NULL; - nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_STATFS(v3)); - if (v3) - nfsm_srvpostop_attr(getret, &at); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_POSTOPATTR(info.v3) + NFSX_STATFS(info.v3), + &error)); + if (info.v3) + nfsm_srvpostop_attr(&info, nfsd, getret, &at); if (error) { error = 0; goto nfsmout; } - nfsm_build(sfp, struct nfs_statfs *, NFSX_STATFS(v3)); - if (v3) { + sfp = nfsm_build(&info, NFSX_STATFS(info.v3)); + if (info.v3) { tval = (u_quad_t)sf->f_blocks; tval *= (u_quad_t)sf->f_bsize; txdr_hyper(tval, &sfp->sf_tbytes); @@ -3597,6 +3723,7 @@ nfsrv_statfs(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, sfp->sf_bavail = txdr_unsigned(sf->f_bavail); } nfsmout: + *mrq = info.mreq; if (vp) vput(vp); return(error); @@ -3609,17 +3736,10 @@ int nfsrv_fsinfo(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq) { - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; struct ucred *cred = &nfsd->nd_cr; - u_int32_t *tl; struct nfsv3_fsinfo *sip; - int32_t t1; - caddr_t bpos; int error = 0, rdonly, getret = 1, pref; - char *cp2; - struct mbuf *mb, *mb2, *mreq; struct vnode *vp = NULL; struct mount *mp = NULL; struct vattr at; @@ -3627,15 +3747,21 @@ nfsrv_fsinfo(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, fhandle_t *fhp; u_quad_t maxfsize; struct statfs sb; + struct nfsm_info info; + + info.mrep = nfsd->nd_mrep; + info.mreq = NULL; + info.md = nfsd->nd_md; + info.dpos = nfsd->nd_dpos; nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); + NEGREPLYOUT(nfsm_srvmtofh(&info, nfsd, fhp, &error)); error = nfsrv_fhtovp(fhp, 1, &mp, &vp, cred, slp, nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (error) { - nfsm_reply(NFSX_UNSIGNED); - nfsm_srvpostop_attr(getret, &at); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, NFSX_UNSIGNED, &error)); + nfsm_srvpostop_attr(&info, nfsd, getret, &at); error = 0; goto nfsmout; } @@ -3647,9 +3773,10 @@ nfsrv_fsinfo(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, getret = VOP_GETATTR(vp, &at); vput(vp); vp = NULL; - nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3FSINFO); - nfsm_srvpostop_attr(getret, &at); - nfsm_build(sip, struct nfsv3_fsinfo *, NFSX_V3FSINFO); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_V3POSTOPATTR + NFSX_V3FSINFO, &error)); + nfsm_srvpostop_attr(&info, nfsd, getret, &at); + sip = nfsm_build(&info, NFSX_V3FSINFO); /* * XXX @@ -3674,6 +3801,7 @@ nfsrv_fsinfo(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, NFSV3FSINFO_SYMLINK | NFSV3FSINFO_HOMOGENEOUS | NFSV3FSINFO_CANSETTIME); nfsmout: + *mrq = info.mreq; if (vp) vput(vp); return(error); @@ -3686,32 +3814,31 @@ int nfsrv_pathconf(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq) { - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; struct ucred *cred = &nfsd->nd_cr; - u_int32_t *tl; struct nfsv3_pathconf *pc; - int32_t t1; - caddr_t bpos; int error = 0, rdonly, getret = 1; register_t linkmax, namemax, chownres, notrunc; - char *cp2; - struct mbuf *mb, *mb2, *mreq; struct vnode *vp = NULL; struct mount *mp = NULL; struct vattr at; nfsfh_t nfh; fhandle_t *fhp; + struct nfsm_info info; + + info.mrep = nfsd->nd_mrep; + info.mreq = NULL; + info.md = nfsd->nd_md; + info.dpos = nfsd->nd_dpos; nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); + NEGREPLYOUT(nfsm_srvmtofh(&info, nfsd, fhp, &error)); error = nfsrv_fhtovp(fhp, 1, &mp, &vp, cred, slp, nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH), TRUE); if (error) { - nfsm_reply(NFSX_UNSIGNED); - nfsm_srvpostop_attr(getret, &at); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, NFSX_UNSIGNED, &error)); + nfsm_srvpostop_attr(&info, nfsd, getret, &at); error = 0; goto nfsmout; } @@ -3725,13 +3852,15 @@ nfsrv_pathconf(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, getret = VOP_GETATTR(vp, &at); vput(vp); vp = NULL; - nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3PATHCONF); - nfsm_srvpostop_attr(getret, &at); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, + NFSX_V3POSTOPATTR + NFSX_V3PATHCONF, + &error)); + nfsm_srvpostop_attr(&info, nfsd, getret, &at); if (error) { error = 0; goto nfsmout; } - nfsm_build(pc, struct nfsv3_pathconf *, NFSX_V3PATHCONF); + pc = nfsm_build(&info, NFSX_V3PATHCONF); pc->pc_linkmax = txdr_unsigned(linkmax); pc->pc_namemax = txdr_unsigned(namemax); @@ -3746,6 +3875,7 @@ nfsrv_pathconf(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, pc->pc_caseinsensitive = nfs_false; pc->pc_casepreserving = nfs_true; nfsmout: + *mrq = info.mreq; if (vp) vput(vp); return(error); @@ -3759,14 +3889,17 @@ int nfsrv_null(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq) { - struct mbuf *mrep = nfsd->nd_mrep; - caddr_t bpos; + struct nfsm_info info; int error = NFSERR_RETVOID; - struct mbuf *mb, *mreq; + + info.mrep = nfsd->nd_mrep; + info.mreq = NULL; nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); - nfsm_reply(0); - nfsm_srvdone; + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, 0, &error)); +nfsmout: + *mrq = info.mreq; + return (error); } /* @@ -3777,19 +3910,22 @@ int nfsrv_noop(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct thread *td, struct mbuf **mrq) { - struct mbuf *mrep = nfsd->nd_mrep; - caddr_t bpos; + struct nfsm_info info; int error; - struct mbuf *mb, *mreq; + + info.mrep = nfsd->nd_mrep; + info.mreq = NULL; nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); if (nfsd->nd_repstat) error = nfsd->nd_repstat; else error = EPROCUNAVAIL; - nfsm_reply(0); + NEGKEEPOUT(nfsm_reply(&info, nfsd, slp, 0, &error)); error = 0; - nfsm_srvdone; +nfsmout: + *mrq = info.mreq; + return (error); } /* diff --git a/sys/vfs/nfs/nfs_socket.c b/sys/vfs/nfs/nfs_socket.c index 1bbfefad7d..644ee1e26d 100644 --- a/sys/vfs/nfs/nfs_socket.c +++ b/sys/vfs/nfs/nfs_socket.c @@ -759,12 +759,12 @@ nfs_reply(struct nfsreq *myrep) { struct nfsreq *rep; struct nfsmount *nmp = myrep->r_nmp; - int32_t t1; - struct mbuf *mrep, *md; struct sockaddr *nam; - u_int32_t rxid, *tl; - caddr_t dpos, cp2; + u_int32_t rxid; + u_int32_t *tl; int error; + struct nfsm_info info; + int t1; /* * Loop around until we get our own reply @@ -782,6 +782,8 @@ nfs_reply(struct nfsreq *myrep) * case, the lock is not taken to avoid races with * other processes. */ + info.mrep = NULL; + error = nfs_rcvlock(myrep); if (error == EALREADY) return (0); @@ -790,7 +792,7 @@ nfs_reply(struct nfsreq *myrep) /* * Get the next Rpc reply off the socket */ - error = nfs_receive(myrep, &nam, &mrep); + error = nfs_receive(myrep, &nam, &info.mrep); nfs_rcvunlock(myrep); if (error) { /* @@ -810,13 +812,14 @@ nfs_reply(struct nfsreq *myrep) /* * Get the xid and check that it is an rpc reply */ - md = mrep; - dpos = mtod(md, caddr_t); - nfsm_dissect(tl, u_int32_t *, 2*NFSX_UNSIGNED); + info.md = info.mrep; + info.dpos = mtod(info.md, caddr_t); + NULLOUT(tl = nfsm_dissect(&info, 2*NFSX_UNSIGNED)); rxid = *tl++; if (*tl != rpc_reply) { nfsstats.rpcinvalid++; - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; nfsmout: if (myrep->r_flags & R_GETONEREP) return (0); @@ -841,8 +844,8 @@ nfsmout: * Fill in the rest of the reply if we found a match. */ if (rep) { - rep->r_md = md; - rep->r_dpos = dpos; + rep->r_md = info.md; + rep->r_dpos = info.dpos; if (nfsrtton) { struct rttl *rt; @@ -901,7 +904,7 @@ nfsmout: NFS_SDRTT(rep) += t1; } nmp->nm_timeouts = 0; - rep->r_mrep = mrep; + rep->r_mrep = info.mrep; mtx_abort_ex_link(&rep->r_nmp->nm_rxlock, &rep->r_link); } /* @@ -910,7 +913,8 @@ nfsmout: */ if (rep == NULL) { nfsstats.rpcunexpected++; - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; } else if (rep == myrep) { if (rep->r_mrep == NULL) panic("nfsreply nil"); @@ -1187,14 +1191,11 @@ nfs_request_processreply(struct nfsreq *rep, int error) { struct nfsmount *nmp = rep->r_nmp; time_t waituntil; - caddr_t dpos, cp2; - struct mbuf *mrep; - struct mbuf *md; u_int32_t *tl; int trylater_delay = 15, trylater_cnt = 0; int verf_type; - int t1; int i; + struct nfsm_info info; /* * If there was a successful reply and a tprintf msg. @@ -1203,9 +1204,9 @@ nfs_request_processreply(struct nfsreq *rep, int error) if (!error && (rep->r_flags & R_TPRINTFMSG)) nfs_msg(rep->r_td, nmp->nm_mountp->mnt_stat.f_mntfromname, "is alive again"); - mrep = rep->r_mrep; - md = rep->r_md; - dpos = rep->r_dpos; + info.mrep = rep->r_mrep; + info.md = rep->r_md; + info.dpos = rep->r_dpos; if (error) { m_freem(rep->r_mreq); kfree((caddr_t)rep, M_NFSREQ); @@ -1215,7 +1216,7 @@ nfs_request_processreply(struct nfsreq *rep, int error) /* * break down the rpc header and check if ok */ - nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED); + NULLOUT(tl = nfsm_dissect(&info, 3 * NFSX_UNSIGNED)); if (*tl++ == rpc_msgdenied) { if (*tl == rpc_mismatch) { error = EOPNOTSUPP; @@ -1224,7 +1225,8 @@ nfs_request_processreply(struct nfsreq *rep, int error) if (!rep->r_failed_auth) { rep->r_failed_auth++; rep->r_mheadend->m_next = NULL; - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; m_freem(rep->r_mreq); return (ENEEDAUTH); } else { @@ -1233,7 +1235,8 @@ nfs_request_processreply(struct nfsreq *rep, int error) } else { error = EACCES; } - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; m_freem(rep->r_mreq); kfree((caddr_t)rep, M_NFSREQ); return (error); @@ -1245,21 +1248,23 @@ nfs_request_processreply(struct nfsreq *rep, int error) verf_type = fxdr_unsigned(int, *tl++); i = fxdr_unsigned(int32_t, *tl); if ((nmp->nm_flag & NFSMNT_KERB) && verf_type == RPCAUTH_KERB4) { - error = nfs_savenickauth(nmp, rep->r_cred, i, - rep->r_key, &md, &dpos, mrep); + error = nfs_savenickauth(nmp, rep->r_cred, i, rep->r_key, + &info.md, &info.dpos, info.mrep); if (error) goto nfsmout; - } else if (i > 0) - nfsm_adv(nfsm_rndup(i)); - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + } else if (i > 0) { + ERROROUT(nfsm_adv(&info, nfsm_rndup(i))); + } + NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED)); /* 0 == ok */ if (*tl == 0) { - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED)); if (*tl != 0) { error = fxdr_unsigned(int, *tl); if ((nmp->nm_flag & NFSMNT_NFSV3) && error == NFSERR_TRYLATER) { - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; error = 0; waituntil = time_second + trylater_delay; while (time_second < waituntil) @@ -1291,25 +1296,28 @@ nfs_request_processreply(struct nfsreq *rep, int error) lockmgr(&vp->v_lock, ltype); } if (nmp->nm_flag & NFSMNT_NFSV3) { - *rep->r_mrp = mrep; - *rep->r_mdp = md; - *rep->r_dposp = dpos; + *rep->r_mrp = info.mrep; + *rep->r_mdp = info.md; + *rep->r_dposp = info.dpos; error |= NFSERR_RETERR; - } else - m_freem(mrep); + } else { + m_freem(info.mrep); + info.mrep = NULL; + } m_freem(rep->r_mreq); kfree((caddr_t)rep, M_NFSREQ); return (error); } - *rep->r_mrp = mrep; - *rep->r_mdp = md; - *rep->r_dposp = dpos; + *rep->r_mrp = info.mrep; + *rep->r_mdp = info.md; + *rep->r_dposp = info.dpos; m_freem(rep->r_mreq); FREE((caddr_t)rep, M_NFSREQ); return (0); } - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; error = EPROTONOSUPPORT; nfsmout: m_freem(rep->r_mreq); @@ -1327,22 +1335,21 @@ nfs_rephead(int siz, struct nfsrv_descript *nd, struct nfssvc_sock *slp, int err, struct mbuf **mrq, struct mbuf **mbp, caddr_t *bposp) { u_int32_t *tl; - struct mbuf *mreq; - caddr_t bpos; - struct mbuf *mb, *mb2; + struct nfsm_info info; siz += RPC_REPLYSIZ; - mb = mreq = m_getl(max_hdr + siz, MB_WAIT, MT_DATA, M_PKTHDR, NULL); - mreq->m_pkthdr.len = 0; + info.mb = m_getl(max_hdr + siz, MB_WAIT, MT_DATA, M_PKTHDR, NULL); + info.mreq = info.mb; + info.mreq->m_pkthdr.len = 0; /* * If this is not a cluster, try and leave leading space * for the lower level headers. */ if ((max_hdr + siz) < MINCLSIZE) - mreq->m_data += max_hdr; - tl = mtod(mreq, u_int32_t *); - mreq->m_len = 6 * NFSX_UNSIGNED; - bpos = ((caddr_t)tl) + mreq->m_len; + info.mreq->m_data += max_hdr; + tl = mtod(info.mreq, u_int32_t *); + info.mreq->m_len = 6 * NFSX_UNSIGNED; + info.bpos = ((caddr_t)tl) + info.mreq->m_len; *tl++ = txdr_unsigned(nd->nd_retxid); *tl++ = rpc_reply; if (err == ERPCMISMATCH || (err & NFSERR_AUTHERR)) { @@ -1350,8 +1357,8 @@ nfs_rephead(int siz, struct nfsrv_descript *nd, struct nfssvc_sock *slp, if (err & NFSERR_AUTHERR) { *tl++ = rpc_autherr; *tl = txdr_unsigned(err & ~NFSERR_AUTHERR); - mreq->m_len -= NFSX_UNSIGNED; - bpos -= NFSX_UNSIGNED; + info.mreq->m_len -= NFSX_UNSIGNED; + info.bpos -= NFSX_UNSIGNED; } else { *tl++ = rpc_mismatch; *tl++ = txdr_unsigned(RPC_VER2); @@ -1392,7 +1399,7 @@ nfs_rephead(int siz, struct nfsrv_descript *nd, struct nfssvc_sock *slp, *tl++ = rpc_auth_kerb; *tl++ = txdr_unsigned(3 * NFSX_UNSIGNED); *tl = ktvout.tv_sec; - nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED); + tl = nfsm_build(&info, 3 * NFSX_UNSIGNED); *tl++ = ktvout.tv_usec; *tl++ = txdr_unsigned(nuidp->nu_cr.cr_uid); } else { @@ -1409,7 +1416,7 @@ nfs_rephead(int siz, struct nfsrv_descript *nd, struct nfssvc_sock *slp, break; case EPROGMISMATCH: *tl = txdr_unsigned(RPC_PROGMISMATCH); - nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + tl = nfsm_build(&info, 2 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(2); *tl = txdr_unsigned(3); break; @@ -1422,7 +1429,7 @@ nfs_rephead(int siz, struct nfsrv_descript *nd, struct nfssvc_sock *slp, default: *tl = 0; if (err != NFSERR_RETVOID) { - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); + tl = nfsm_build(&info, NFSX_UNSIGNED); if (err) *tl = txdr_unsigned(nfsrv_errmap(nd, err)); else @@ -1433,9 +1440,9 @@ nfs_rephead(int siz, struct nfsrv_descript *nd, struct nfssvc_sock *slp, } if (mrq != NULL) - *mrq = mreq; - *mbp = mb; - *bposp = bpos; + *mrq = info.mreq; + *mbp = info.mb; + *bposp = info.bpos; if (err != 0 && err != NFSERR_RETVOID) nfsstats.srvrpc_errs++; return (0); @@ -1879,32 +1886,33 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header) { int len, i; u_int32_t *tl; - int32_t t1; struct uio uio; struct iovec iov; - caddr_t dpos, cp2, cp; + caddr_t cp; u_int32_t nfsvers, auth_type; uid_t nickuid; int error = 0, ticklen; - struct mbuf *mrep, *md; struct nfsuid *nuidp; struct timeval tvin, tvout; + struct nfsm_info info; #if 0 /* until encrypted keys are implemented */ NFSKERBKEYSCHED_T keys; /* stores key schedule */ #endif - mrep = nd->nd_mrep; - md = nd->nd_md; - dpos = nd->nd_dpos; + info.mrep = nd->nd_mrep; + info.md = nd->nd_md; + info.dpos = nd->nd_dpos; + if (has_header) { - nfsm_dissect(tl, u_int32_t *, 10 * NFSX_UNSIGNED); + NULLOUT(tl = nfsm_dissect(&info, 10 * NFSX_UNSIGNED)); nd->nd_retxid = fxdr_unsigned(u_int32_t, *tl++); if (*tl++ != rpc_call) { - m_freem(mrep); + m_freem(info.mrep); return (EBADRPC); } - } else - nfsm_dissect(tl, u_int32_t *, 8 * NFSX_UNSIGNED); + } else { + NULLOUT(tl = nfsm_dissect(&info, 8 * NFSX_UNSIGNED)); + } nd->nd_repstat = 0; nd->nd_flag = 0; if (*tl++ != rpc_vers) { @@ -1941,7 +1949,7 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header) auth_type = *tl++; len = fxdr_unsigned(int, *tl++); if (len < 0 || len > RPCAUTH_MAXSIZ) { - m_freem(mrep); + m_freem(info.mrep); return (EBADRPC); } @@ -1952,21 +1960,21 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header) if (auth_type == rpc_auth_unix) { len = fxdr_unsigned(int, *++tl); if (len < 0 || len > NFS_MAXNAMLEN) { - m_freem(mrep); + m_freem(info.mrep); return (EBADRPC); } - nfsm_adv(nfsm_rndup(len)); - nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED); + ERROROUT(nfsm_adv(&info, nfsm_rndup(len))); + NULLOUT(tl = nfsm_dissect(&info, 3 * NFSX_UNSIGNED)); bzero((caddr_t)&nd->nd_cr, sizeof (struct ucred)); nd->nd_cr.cr_ref = 1; nd->nd_cr.cr_uid = fxdr_unsigned(uid_t, *tl++); nd->nd_cr.cr_gid = fxdr_unsigned(gid_t, *tl++); len = fxdr_unsigned(int, *tl); if (len < 0 || len > RPCAUTH_UNIXGIDS) { - m_freem(mrep); + m_freem(info.mrep); return (EBADRPC); } - nfsm_dissect(tl, u_int32_t *, (len + 2) * NFSX_UNSIGNED); + NULLOUT(tl = nfsm_dissect(&info, (len + 2) * NFSX_UNSIGNED)); for (i = 1; i <= len; i++) if (i < NGROUPS) nd->nd_cr.cr_groups[i] = fxdr_unsigned(gid_t, *tl++); @@ -1977,11 +1985,12 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header) nfsrvw_sort(nd->nd_cr.cr_groups, nd->nd_cr.cr_ngroups); len = fxdr_unsigned(int, *++tl); if (len < 0 || len > RPCAUTH_MAXSIZ) { - m_freem(mrep); + m_freem(info.mrep); return (EBADRPC); } - if (len > 0) - nfsm_adv(nfsm_rndup(len)); + if (len > 0) { + ERROROUT(nfsm_adv(&info, nfsm_rndup(len))); + } } else if (auth_type == rpc_auth_kerb) { switch (fxdr_unsigned(int, *tl++)) { case RPCAKN_FULLNAME: @@ -1990,7 +1999,7 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header) uio.uio_resid = nfsm_rndup(ticklen) + NFSX_UNSIGNED; nfsd->nfsd_authlen = uio.uio_resid + NFSX_UNSIGNED; if (uio.uio_resid > (len - 2 * NFSX_UNSIGNED)) { - m_freem(mrep); + m_freem(info.mrep); return (EBADRPC); } uio.uio_offset = 0; @@ -1999,8 +2008,8 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header) uio.uio_segflg = UIO_SYSSPACE; iov.iov_base = (caddr_t)&nfsd->nfsd_authstr[4]; iov.iov_len = RPCAUTH_MAXSIZ - 4; - nfsm_mtouio(&uio, uio.uio_resid); - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + ERROROUT(nfsm_mtouio(&info, &uio, uio.uio_resid)); + NULLOUT(tl = nfsm_dissect(&info, 2 * NFSX_UNSIGNED)); if (*tl++ != rpc_auth_kerb || fxdr_unsigned(int, *tl) != 4 * NFSX_UNSIGNED) { kprintf("Bad kerb verifier\n"); @@ -2008,7 +2017,7 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header) nd->nd_procnum = NFSPROC_NOOP; return (0); } - nfsm_dissect(cp, caddr_t, 4 * NFSX_UNSIGNED); + NULLOUT(cp = nfsm_dissect(&info, 4 * NFSX_UNSIGNED)); tl = (u_int32_t *)cp; if (fxdr_unsigned(int, *tl) != RPCAKN_FULLNAME) { kprintf("Not fullname kerb verifier\n"); @@ -2030,7 +2039,7 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header) return (0); } nickuid = fxdr_unsigned(uid_t, *tl); - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + NULLOUT(tl = nfsm_dissect(&info, 2 * NFSX_UNSIGNED)); if (*tl++ != rpc_auth_kerb || fxdr_unsigned(int, *tl) != 3 * NFSX_UNSIGNED) { kprintf("Kerb nick verifier bad\n"); @@ -2038,7 +2047,7 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header) nd->nd_procnum = NFSPROC_NOOP; return (0); } - nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED); + NULLOUT(tl = nfsm_dissect(&info, 3 * NFSX_UNSIGNED)); tvin.tv_sec = *tl++; tvin.tv_usec = *tl; @@ -2086,8 +2095,8 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header) return (0); } - nd->nd_md = md; - nd->nd_dpos = dpos; + nd->nd_md = info.md; + nd->nd_dpos = info.dpos; return (0); nfsmout: return (error); diff --git a/sys/vfs/nfs/nfs_subs.c b/sys/vfs/nfs/nfs_subs.c index 4051d75de3..60795d6474 100644 --- a/sys/vfs/nfs/nfs_subs.c +++ b/sys/vfs/nfs/nfs_subs.c @@ -637,10 +637,9 @@ nfs_uninit(struct vfsconf *vfsp) * n_mtime or n_attr.mtime due to NACC and NUPD. */ int -nfs_loadattrcache(struct vnode **vpp, struct mbuf **mdp, caddr_t *dposp, +nfs_loadattrcache(struct vnode *vp, struct mbuf **mdp, caddr_t *dposp, struct vattr *vaper, int lattr_flags) { - struct vnode *vp = *vpp; struct vattr *vap; struct nfs_fattr *fp; struct nfsnode *np; diff --git a/sys/vfs/nfs/nfs_syscalls.c b/sys/vfs/nfs/nfs_syscalls.c index 82a54e6385..88f2a1b8df 100644 --- a/sys/vfs/nfs/nfs_syscalls.c +++ b/sys/vfs/nfs/nfs_syscalls.c @@ -1002,15 +1002,17 @@ nfs_savenickauth(struct nfsmount *nmp, struct ucred *cred, int len, { struct nfsuid *nuidp; u_int32_t *tl; - int32_t t1; - struct mbuf *md = *mdp; struct timeval ktvin, ktvout; u_int32_t nick; - char *dpos = *dposp, *cp2; int deltasec, error = 0; + struct nfsm_info info; + + info.md = *mdp; + info.dpos = *dposp; + info.mrep = mrep; if (len == (3 * NFSX_UNSIGNED)) { - nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED); + NULLOUT(tl = nfsm_dissect(&info, 3 * NFSX_UNSIGNED)); ktvin.tv_sec = *tl++; ktvin.tv_usec = *tl++; nick = fxdr_unsigned(u_int32_t, *tl); @@ -1052,10 +1054,11 @@ nfs_savenickauth(struct nfsmount *nmp, struct ucred *cred, int len, LIST_INSERT_HEAD(NMUIDHASH(nmp, cred->cr_uid), nuidp, nu_hash); } - } else - nfsm_adv(nfsm_rndup(len)); + } else { + ERROROUT(nfsm_adv(&info, nfsm_rndup(len))); + } nfsmout: - *mdp = md; - *dposp = dpos; + *mdp = info.md; + *dposp = info.dpos; return (error); } diff --git a/sys/vfs/nfs/nfs_vfsops.c b/sys/vfs/nfs/nfs_vfsops.c index dbb4e68cda..0a8adbbd27 100644 --- a/sys/vfs/nfs/nfs_vfsops.c +++ b/sys/vfs/nfs/nfs_vfsops.c @@ -294,16 +294,15 @@ nfs_statfs(struct mount *mp, struct statfs *sbp, struct ucred *cred) { struct vnode *vp; struct nfs_statfs *sfp; - caddr_t cp; - u_int32_t *tl; - int32_t t1, t2; - caddr_t bpos, dpos, cp2; struct nfsmount *nmp = VFSTONFS(mp); thread_t td = curthread; - int error = 0, v3 = (nmp->nm_flag & NFSMNT_NFSV3), retattr; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; + int error = 0, retattr; struct nfsnode *np; u_quad_t tquad; + struct nfsm_info info; + + info.mrep = NULL; + info.v3 = (nmp->nm_flag & NFSMNT_NFSV3); #ifndef nolint sfp = NULL; @@ -315,24 +314,26 @@ nfs_statfs(struct mount *mp, struct statfs *sbp, struct ucred *cred) /* ignore the passed cred */ cred = crget(); cred->cr_ngroups = 1; - if (v3 && (nmp->nm_state & NFSSTA_GOTFSINFO) == 0) + if (info.v3 && (nmp->nm_state & NFSSTA_GOTFSINFO) == 0) (void)nfs_fsinfo(nmp, vp, td); nfsstats.rpccnt[NFSPROC_FSSTAT]++; - nfsm_reqhead(vp, NFSPROC_FSSTAT, NFSX_FH(v3)); - nfsm_fhtom(vp, v3); - nfsm_request(vp, NFSPROC_FSSTAT, td, cred); - if (v3) - nfsm_postop_attr(vp, retattr, NFS_LATTR_NOSHRINK); + nfsm_reqhead(&info, vp, NFSPROC_FSSTAT, NFSX_FH(info.v3)); + ERROROUT(nfsm_fhtom(&info, vp)); + NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_FSSTAT, td, cred, &error)); + if (info.v3) { + ERROROUT(nfsm_postop_attr(&info, vp, &retattr, + NFS_LATTR_NOSHRINK)); + } if (error) { - if (mrep != NULL) - m_freem(mrep); + if (info.mrep != NULL) + m_freem(info.mrep); goto nfsmout; } - nfsm_dissect(sfp, struct nfs_statfs *, NFSX_STATFS(v3)); + NULLOUT(sfp = nfsm_dissect(&info, NFSX_STATFS(info.v3))); sbp->f_flags = nmp->nm_flag; - sbp->f_iosize = nfs_iosize(v3, nmp->nm_sotype); + sbp->f_iosize = nfs_iosize(info.v3, nmp->nm_sotype); - if (v3) { + if (info.v3) { sbp->f_bsize = NFS_FABLKSIZE; tquad = fxdr_hyper(&sfp->sf_tbytes); sbp->f_blocks = (long)(tquad / ((u_quad_t)NFS_FABLKSIZE)); @@ -356,7 +357,8 @@ nfs_statfs(struct mount *mp, struct statfs *sbp, struct ucred *cred) sbp->f_type = mp->mnt_vfc->vfc_typenum; bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); } - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; nfsmout: vput(vp); crfree(cred); @@ -370,21 +372,20 @@ int nfs_fsinfo(struct nfsmount *nmp, struct vnode *vp, struct thread *td) { struct nfsv3_fsinfo *fsp; - caddr_t cp; - int32_t t1, t2; - u_int32_t *tl, pref, max; - caddr_t bpos, dpos, cp2; + u_int32_t pref, max; int error = 0, retattr; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; u_int64_t maxfsize; + struct nfsm_info info; + info.v3 = 1; nfsstats.rpccnt[NFSPROC_FSINFO]++; - nfsm_reqhead(vp, NFSPROC_FSINFO, NFSX_FH(1)); - nfsm_fhtom(vp, 1); - nfsm_request(vp, NFSPROC_FSINFO, td, nfs_vpcred(vp, ND_READ)); - nfsm_postop_attr(vp, retattr, NFS_LATTR_NOSHRINK); - if (!error) { - nfsm_dissect(fsp, struct nfsv3_fsinfo *, NFSX_V3FSINFO); + nfsm_reqhead(&info, vp, NFSPROC_FSINFO, NFSX_FH(1)); + ERROROUT(nfsm_fhtom(&info, vp)); + NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_FSINFO, td, + nfs_vpcred(vp, ND_READ), &error)); + ERROROUT(nfsm_postop_attr(&info, vp, &retattr, NFS_LATTR_NOSHRINK)); + if (error == 0) { + NULLOUT(fsp = nfsm_dissect(&info, NFSX_V3FSINFO)); pref = fxdr_unsigned(u_int32_t, fsp->fs_wtpref); if (pref < nmp->nm_wsize && pref >= NFS_FABLKSIZE) nmp->nm_wsize = (pref + NFS_FABLKSIZE - 1) & @@ -419,7 +420,8 @@ nfs_fsinfo(struct nfsmount *nmp, struct vnode *vp, struct thread *td) nmp->nm_maxfilesize = maxfsize; nmp->nm_state |= NFSSTA_GOTFSINFO; } - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; nfsmout: return (error); } diff --git a/sys/vfs/nfs/nfs_vnops.c b/sys/vfs/nfs/nfs_vnops.c index b12425b8f1..f7a62ae4a3 100644 --- a/sys/vfs/nfs/nfs_vnops.c +++ b/sys/vfs/nfs/nfs_vnops.c @@ -252,32 +252,33 @@ static int nfs3_access_otw(struct vnode *vp, int wmode, struct thread *td, struct ucred *cred) { - const int v3 = 1; + struct nfsnode *np = VTONFS(vp); + int attrflag; + int error = 0; u_int32_t *tl; - int error = 0, attrflag; - - struct mbuf *mreq, *mrep, *md, *mb, *mb2; - caddr_t bpos, dpos, cp2; - int32_t t1, t2; - caddr_t cp; u_int32_t rmode; - struct nfsnode *np = VTONFS(vp); + struct nfsm_info info; + + info.mrep = NULL; + info.v3 = 1; nfsstats.rpccnt[NFSPROC_ACCESS]++; - nfsm_reqhead(vp, NFSPROC_ACCESS, NFSX_FH(v3) + NFSX_UNSIGNED); - nfsm_fhtom(vp, v3); - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); + nfsm_reqhead(&info, vp, NFSPROC_ACCESS, + NFSX_FH(info.v3) + NFSX_UNSIGNED); + ERROROUT(nfsm_fhtom(&info, vp)); + tl = nfsm_build(&info, NFSX_UNSIGNED); *tl = txdr_unsigned(wmode); - nfsm_request(vp, NFSPROC_ACCESS, td, cred); - nfsm_postop_attr(vp, attrflag, NFS_LATTR_NOSHRINK); - if (!error) { - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_ACCESS, td, cred, &error)); + ERROROUT(nfsm_postop_attr(&info, vp, &attrflag, NFS_LATTR_NOSHRINK)); + if (error == 0) { + NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED)); rmode = fxdr_unsigned(u_int32_t, *tl); np->n_mode = rmode; np->n_modeuid = cred->cr_uid; np->n_modestamp = mycpu->gd_time_seconds; } - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; nfsmout: return error; } @@ -297,8 +298,8 @@ nfs_access(struct vop_access_args *ap) thread_t td = curthread; int error = 0; u_int32_t mode, wmode; - int v3 = NFS_ISV3(vp); struct nfsnode *np = VTONFS(vp); + int v3 = NFS_ISV3(vp); /* * Disallow write attempts on filesystems mounted read-only; @@ -610,14 +611,12 @@ nfs_getattr(struct vop_getattr_args *ap) { struct vnode *vp = ap->a_vp; struct nfsnode *np = VTONFS(vp); - caddr_t cp; - u_int32_t *tl; - int32_t t1, t2; - caddr_t bpos, dpos; int error = 0; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; - int v3 = NFS_ISV3(vp); thread_t td = curthread; + struct nfsm_info info; + + info.mrep = NULL; + info.v3 = NFS_ISV3(vp); /* * Update local times for special files. @@ -630,7 +629,7 @@ nfs_getattr(struct vop_getattr_args *ap) if (nfs_getattrcache(vp, ap->a_vap) == 0) return (0); - if (v3 && nfsaccess_cache_timeout > 0) { + if (info.v3 && nfsaccess_cache_timeout > 0) { nfsstats.accesscache_misses++; nfs3_access_otw(vp, NFSV3ACCESS_ALL, td, nfs_vpcred(vp, ND_CHECK)); if (nfs_getattrcache(vp, ap->a_vap) == 0) @@ -638,13 +637,15 @@ nfs_getattr(struct vop_getattr_args *ap) } nfsstats.rpccnt[NFSPROC_GETATTR]++; - nfsm_reqhead(vp, NFSPROC_GETATTR, NFSX_FH(v3)); - nfsm_fhtom(vp, v3); - nfsm_request(vp, NFSPROC_GETATTR, td, nfs_vpcred(vp, ND_CHECK)); - if (!error) { - nfsm_loadattr(vp, ap->a_vap); + nfsm_reqhead(&info, vp, NFSPROC_GETATTR, NFSX_FH(info.v3)); + ERROROUT(nfsm_fhtom(&info, vp)); + NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_GETATTR, td, + nfs_vpcred(vp, ND_CHECK), &error)); + if (error == 0) { + ERROROUT(nfsm_loadattr(&info, vp, ap->a_vap)); } - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; nfsmout: return (error); } @@ -797,23 +798,23 @@ nfs_setattrrpc(struct vnode *vp, struct vattr *vap, { struct nfsv2_sattr *sp; struct nfsnode *np = VTONFS(vp); - caddr_t cp; - int32_t t1, t2; - caddr_t bpos, dpos, cp2; u_int32_t *tl; int error = 0, wccflag = NFSV3_WCCRATTR; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; - int v3 = NFS_ISV3(vp); + struct nfsm_info info; + + info.mrep = NULL; + info.v3 = NFS_ISV3(vp); nfsstats.rpccnt[NFSPROC_SETATTR]++; - nfsm_reqhead(vp, NFSPROC_SETATTR, NFSX_FH(v3) + NFSX_SATTR(v3)); - nfsm_fhtom(vp, v3); - if (v3) { - nfsm_v3attrbuild(vap, TRUE); - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); + nfsm_reqhead(&info, vp, NFSPROC_SETATTR, + NFSX_FH(info.v3) + NFSX_SATTR(info.v3)); + ERROROUT(nfsm_fhtom(&info, vp)); + if (info.v3) { + nfsm_v3attrbuild(&info, vap, TRUE); + tl = nfsm_build(&info, NFSX_UNSIGNED); *tl = nfs_false; } else { - nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR); + sp = nfsm_build(&info, NFSX_V2SATTR); if (vap->va_mode == (mode_t)VNOVAL) sp->sa_mode = nfs_xdrneg1; else @@ -830,13 +831,15 @@ nfs_setattrrpc(struct vnode *vp, struct vattr *vap, txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); } - nfsm_request(vp, NFSPROC_SETATTR, td, cred); - if (v3) { + NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_SETATTR, td, cred, &error)); + if (info.v3) { np->n_modestamp = 0; - nfsm_wcc_data(vp, wccflag); - } else - nfsm_loadattr(vp, NULL); - m_freem(mrep); + ERROROUT(nfsm_wcc_data(&info, vp, &wccflag)); + } else { + ERROROUT(nfsm_loadattr(&info, vp, NULL)); + } + m_freem(info.mrep); + info.mrep = NULL; nfsmout: return (error); } @@ -874,12 +877,7 @@ nfs_nresolve(struct vop_nresolve_args *ap) int fhsize; int error; int len; - int v3; - /******NFSM MACROS********/ - struct mbuf *mb, *mrep, *mreq, *mb2, *md; - caddr_t bpos, dpos, cp, cp2; - u_int32_t *tl; - int32_t t1, t2; + struct nfsm_info info; cred = ap->a_cred; dvp = ap->a_dvp; @@ -887,17 +885,20 @@ nfs_nresolve(struct vop_nresolve_args *ap) if ((error = vget(dvp, LK_SHARED)) != 0) return (error); + info.mrep = NULL; + info.v3 = NFS_ISV3(dvp); + nvp = NULL; - v3 = NFS_ISV3(dvp); nfsstats.lookupcache_misses++; nfsstats.rpccnt[NFSPROC_LOOKUP]++; ncp = ap->a_nch->ncp; len = ncp->nc_nlen; - nfsm_reqhead(dvp, NFSPROC_LOOKUP, - NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len)); - nfsm_fhtom(dvp, v3); - nfsm_strtom(ncp->nc_name, len, NFS_MAXNAMLEN); - nfsm_request(dvp, NFSPROC_LOOKUP, td, ap->a_cred); + nfsm_reqhead(&info, dvp, NFSPROC_LOOKUP, + NFSX_FH(info.v3) + NFSX_UNSIGNED + nfsm_rndup(len)); + ERROROUT(nfsm_fhtom(&info, dvp)); + ERROROUT(nfsm_strtom(&info, ncp->nc_name, len, NFS_MAXNAMLEN)); + NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_LOOKUP, td, + ap->a_cred, &error)); if (error) { /* * Cache negatve lookups to reduce NFS traffic, but use @@ -909,8 +910,10 @@ nfs_nresolve(struct vop_nresolve_args *ap) */ if (error == ENOENT) nfs_cache_setvp(ap->a_nch, NULL, nfsneg_cache_timeout); - nfsm_postop_attr(dvp, attrflag, NFS_LATTR_NOSHRINK); - m_freem(mrep); + ERROROUT(nfsm_postop_attr(&info, dvp, &attrflag, + NFS_LATTR_NOSHRINK)); + m_freem(info.mrep); + info.mrep = NULL; goto nfsmout; } @@ -928,7 +931,7 @@ nfs_nresolve(struct vop_nresolve_args *ap) * of a bad hack here the rest of the NFS client code needs to do * the right thing. */ - nfsm_getfh(fhp, fhsize, v3); + NEGATIVEOUT(fhsize = nfsm_getfh(&info, &fhp)); np = VTONFS(dvp); if (NFS_CMPFH(np, fhp, fhsize)) { @@ -937,20 +940,24 @@ nfs_nresolve(struct vop_nresolve_args *ap) } else { error = nfs_nget(dvp->v_mount, fhp, fhsize, &np); if (error) { - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; vput(dvp); return (error); } nvp = NFSTOV(np); } - if (v3) { - nfsm_postop_attr(nvp, attrflag, NFS_LATTR_NOSHRINK); - nfsm_postop_attr(dvp, attrflag, NFS_LATTR_NOSHRINK); + if (info.v3) { + ERROROUT(nfsm_postop_attr(&info, nvp, &attrflag, + NFS_LATTR_NOSHRINK)); + ERROROUT(nfsm_postop_attr(&info, dvp, &attrflag, + NFS_LATTR_NOSHRINK)); } else { - nfsm_loadattr(nvp, NULL); + ERROROUT(nfsm_loadattr(&info, nvp, NULL)); } nfs_cache_setvp(ap->a_nch, nvp, nfspos_cache_timeout); - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; nfsmout: vput(dvp); if (nvp) { @@ -978,17 +985,15 @@ nfs_lookup(struct vop_old_lookup_args *ap) struct vnode **vpp = ap->a_vpp; int flags = cnp->cn_flags; struct vnode *newvp; - u_int32_t *tl; - caddr_t cp; - int32_t t1, t2; struct nfsmount *nmp; - caddr_t bpos, dpos, cp2; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; long len; nfsfh_t *fhp; struct nfsnode *np; int lockparent, wantparent, error = 0, attrflag, fhsize; - int v3 = NFS_ISV3(dvp); + struct nfsm_info info; + + info.mrep = NULL; + info.v3 = NFS_ISV3(dvp); /* * Read-only mount check and directory check. @@ -1020,39 +1025,48 @@ nfs_lookup(struct vop_old_lookup_args *ap) nfsstats.lookupcache_misses++; nfsstats.rpccnt[NFSPROC_LOOKUP]++; len = cnp->cn_namelen; - nfsm_reqhead(dvp, NFSPROC_LOOKUP, - NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len)); - nfsm_fhtom(dvp, v3); - nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN); - nfsm_request(dvp, NFSPROC_LOOKUP, cnp->cn_td, cnp->cn_cred); + nfsm_reqhead(&info, dvp, NFSPROC_LOOKUP, + NFSX_FH(info.v3) + NFSX_UNSIGNED + nfsm_rndup(len)); + ERROROUT(nfsm_fhtom(&info, dvp)); + ERROROUT(nfsm_strtom(&info, cnp->cn_nameptr, len, NFS_MAXNAMLEN)); + NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_LOOKUP, cnp->cn_td, + cnp->cn_cred, &error)); if (error) { - nfsm_postop_attr(dvp, attrflag, NFS_LATTR_NOSHRINK); - m_freem(mrep); + ERROROUT(nfsm_postop_attr(&info, dvp, &attrflag, + NFS_LATTR_NOSHRINK)); + m_freem(info.mrep); + info.mrep = NULL; goto nfsmout; } - nfsm_getfh(fhp, fhsize, v3); + NEGATIVEOUT(fhsize = nfsm_getfh(&info, &fhp)); /* * Handle RENAME case... */ if (cnp->cn_nameiop == NAMEI_RENAME && wantparent) { if (NFS_CMPFH(np, fhp, fhsize)) { - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; return (EISDIR); } error = nfs_nget(dvp->v_mount, fhp, fhsize, &np); if (error) { - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; return (error); } newvp = NFSTOV(np); - if (v3) { - nfsm_postop_attr(newvp, attrflag, NFS_LATTR_NOSHRINK); - nfsm_postop_attr(dvp, attrflag, NFS_LATTR_NOSHRINK); - } else - nfsm_loadattr(newvp, NULL); + if (info.v3) { + ERROROUT(nfsm_postop_attr(&info, newvp, &attrflag, + NFS_LATTR_NOSHRINK)); + ERROROUT(nfsm_postop_attr(&info, dvp, &attrflag, + NFS_LATTR_NOSHRINK)); + } else { + ERROROUT(nfsm_loadattr(&info, newvp, NULL)); + } *vpp = newvp; - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; if (!lockparent) { vn_unlock(dvp); cnp->cn_flags |= CNP_PDIRUNLOCK; @@ -1084,7 +1098,8 @@ nfs_lookup(struct vop_old_lookup_args *ap) } else { error = nfs_nget(dvp->v_mount, fhp, fhsize, &np); if (error) { - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; return (error); } if (!lockparent) { @@ -1093,11 +1108,14 @@ nfs_lookup(struct vop_old_lookup_args *ap) } newvp = NFSTOV(np); } - if (v3) { - nfsm_postop_attr(newvp, attrflag, NFS_LATTR_NOSHRINK); - nfsm_postop_attr(dvp, attrflag, NFS_LATTR_NOSHRINK); - } else - nfsm_loadattr(newvp, NULL); + if (info.v3) { + ERROROUT(nfsm_postop_attr(&info, newvp, &attrflag, + NFS_LATTR_NOSHRINK)); + ERROROUT(nfsm_postop_attr(&info, dvp, &attrflag, + NFS_LATTR_NOSHRINK)); + } else { + ERROROUT(nfsm_loadattr(&info, newvp, NULL)); + } #if 0 /* XXX MOVE TO nfs_nremove() */ if ((cnp->cn_flags & CNP_MAKEENTRY) && @@ -1106,7 +1124,8 @@ nfs_lookup(struct vop_old_lookup_args *ap) } #endif *vpp = newvp; - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; nfsmout: if (error) { if (newvp != NULLVP) { @@ -1166,30 +1185,32 @@ nfs_readlink(struct vop_readlink_args *ap) int nfs_readlinkrpc(struct vnode *vp, struct uio *uiop) { - u_int32_t *tl; - caddr_t cp; - int32_t t1, t2; - caddr_t bpos, dpos, cp2; int error = 0, len, attrflag; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; - int v3 = NFS_ISV3(vp); + struct nfsm_info info; + + info.mrep = NULL; + info.v3 = NFS_ISV3(vp); nfsstats.rpccnt[NFSPROC_READLINK]++; - nfsm_reqhead(vp, NFSPROC_READLINK, NFSX_FH(v3)); - nfsm_fhtom(vp, v3); - nfsm_request(vp, NFSPROC_READLINK, uiop->uio_td, nfs_vpcred(vp, ND_CHECK)); - if (v3) - nfsm_postop_attr(vp, attrflag, NFS_LATTR_NOSHRINK); + nfsm_reqhead(&info, vp, NFSPROC_READLINK, NFSX_FH(info.v3)); + ERROROUT(nfsm_fhtom(&info, vp)); + NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_READLINK, uiop->uio_td, + nfs_vpcred(vp, ND_CHECK), &error)); + if (info.v3) { + ERROROUT(nfsm_postop_attr(&info, vp, &attrflag, + NFS_LATTR_NOSHRINK)); + } if (!error) { - nfsm_strsiz(len, NFS_MAXPATHLEN); + NEGATIVEOUT(len = nfsm_strsiz(&info, NFS_MAXPATHLEN)); if (len == NFS_MAXPATHLEN) { struct nfsnode *np = VTONFS(vp); if (np->n_size && np->n_size < NFS_MAXPATHLEN) len = np->n_size; } - nfsm_mtouio(uiop, len); + ERROROUT(nfsm_mtouio(&info, uiop, len)); } - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; nfsmout: return (error); } @@ -1202,13 +1223,12 @@ int nfs_readrpc(struct vnode *vp, struct uio *uiop) { u_int32_t *tl; - caddr_t cp; - int32_t t1, t2; - caddr_t bpos, dpos, cp2; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; struct nfsmount *nmp; int error = 0, len, retlen, tsiz, eof, attrflag; - int v3 = NFS_ISV3(vp); + struct nfsm_info info; + + info.mrep = NULL; + info.v3 = NFS_ISV3(vp); #ifndef nolint eof = 0; @@ -1220,10 +1240,11 @@ nfs_readrpc(struct vnode *vp, struct uio *uiop) while (tsiz > 0) { nfsstats.rpccnt[NFSPROC_READ]++; len = (tsiz > nmp->nm_rsize) ? nmp->nm_rsize : tsiz; - nfsm_reqhead(vp, NFSPROC_READ, NFSX_FH(v3) + NFSX_UNSIGNED * 3); - nfsm_fhtom(vp, v3); - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED * 3); - if (v3) { + nfsm_reqhead(&info, vp, NFSPROC_READ, + NFSX_FH(info.v3) + NFSX_UNSIGNED * 3); + ERROROUT(nfsm_fhtom(&info, vp)); + tl = nfsm_build(&info, NFSX_UNSIGNED * 3); + if (info.v3) { txdr_hyper(uiop->uio_offset, tl); *(tl + 2) = txdr_unsigned(len); } else { @@ -1231,22 +1252,22 @@ nfs_readrpc(struct vnode *vp, struct uio *uiop) *tl++ = txdr_unsigned(len); *tl = 0; } - nfsm_request(vp, NFSPROC_READ, uiop->uio_td, nfs_vpcred(vp, ND_READ)); - if (v3) { - nfsm_postop_attr(vp, attrflag, NFS_LATTR_NOSHRINK); - if (error) { - m_freem(mrep); - goto nfsmout; - } - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_READ, uiop->uio_td, + nfs_vpcred(vp, ND_READ), &error)); + if (info.v3) { + ERROROUT(nfsm_postop_attr(&info, vp, &attrflag, + NFS_LATTR_NOSHRINK)); + NULLOUT(tl = nfsm_dissect(&info, 2 * NFSX_UNSIGNED)); eof = fxdr_unsigned(int, *(tl + 1)); - } else - nfsm_loadattr(vp, NULL); - nfsm_strsiz(retlen, nmp->nm_rsize); - nfsm_mtouio(uiop, retlen); - m_freem(mrep); + } else { + ERROROUT(nfsm_loadattr(&info, vp, NULL)); + } + NEGATIVEOUT(retlen = nfsm_strsiz(&info, nmp->nm_rsize)); + ERROROUT(nfsm_mtouio(&info, uiop, retlen)); + m_freem(info.mrep); + info.mrep = NULL; tsiz -= retlen; - if (v3) { + if (info.v3) { if (eof || retlen == 0) { tsiz = 0; } @@ -1265,13 +1286,14 @@ int nfs_writerpc(struct vnode *vp, struct uio *uiop, int *iomode, int *must_commit) { u_int32_t *tl; - caddr_t cp; - int32_t t1, t2, backup; - caddr_t bpos, dpos, cp2; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; + int32_t backup; struct nfsmount *nmp = VFSTONFS(vp->v_mount); int error = 0, len, tsiz, wccflag = NFSV3_WCCRATTR, rlen, commit; - int v3 = NFS_ISV3(vp), committed = NFSV3WRITE_FILESYNC; + int committed = NFSV3WRITE_FILESYNC; + struct nfsm_info info; + + info.mrep = NULL; + info.v3 = NFS_ISV3(vp); #ifndef DIAGNOSTIC if (uiop->uio_iovcnt != 1) @@ -1284,11 +1306,11 @@ nfs_writerpc(struct vnode *vp, struct uio *uiop, int *iomode, int *must_commit) while (tsiz > 0) { nfsstats.rpccnt[NFSPROC_WRITE]++; len = (tsiz > nmp->nm_wsize) ? nmp->nm_wsize : tsiz; - nfsm_reqhead(vp, NFSPROC_WRITE, - NFSX_FH(v3) + 5 * NFSX_UNSIGNED + nfsm_rndup(len)); - nfsm_fhtom(vp, v3); - if (v3) { - nfsm_build(tl, u_int32_t *, 5 * NFSX_UNSIGNED); + nfsm_reqhead(&info, vp, NFSPROC_WRITE, + NFSX_FH(info.v3) + 5 * NFSX_UNSIGNED + nfsm_rndup(len)); + ERROROUT(nfsm_fhtom(&info, vp)); + if (info.v3) { + tl = nfsm_build(&info, 5 * NFSX_UNSIGNED); txdr_hyper(uiop->uio_offset, tl); tl += 2; *tl++ = txdr_unsigned(len); @@ -1297,7 +1319,7 @@ nfs_writerpc(struct vnode *vp, struct uio *uiop, int *iomode, int *must_commit) } else { u_int32_t x; - nfsm_build(tl, u_int32_t *, 4 * NFSX_UNSIGNED); + tl = nfsm_build(&info, 4 * NFSX_UNSIGNED); /* Set both "begin" and "current" to non-garbage. */ x = txdr_unsigned((u_int32_t)uiop->uio_offset); *tl++ = x; /* "begin offset" */ @@ -1306,9 +1328,10 @@ nfs_writerpc(struct vnode *vp, struct uio *uiop, int *iomode, int *must_commit) *tl++ = x; /* total to this offset */ *tl = x; /* size of this write */ } - nfsm_uiotom(uiop, len); - nfsm_request(vp, NFSPROC_WRITE, uiop->uio_td, nfs_vpcred(vp, ND_WRITE)); - if (v3) { + ERROROUT(nfsm_uiotom(&info, uiop, len)); + NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_WRITE, uiop->uio_td, + nfs_vpcred(vp, ND_WRITE), &error)); + if (info.v3) { /* * The write RPC returns a before and after mtime. The * nfsm_wcc_data() macro checks the before n_mtime @@ -1318,14 +1341,14 @@ nfs_writerpc(struct vnode *vp, struct uio *uiop, int *iomode, int *must_commit) * time did not match the original mtime. */ wccflag = NFSV3_WCCCHK; - nfsm_wcc_data(vp, wccflag); - if (!error) { - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED - + NFSX_V3WRITEVERF); + ERROROUT(nfsm_wcc_data(&info, vp, &wccflag)); + if (error == 0) { + NULLOUT(tl = nfsm_dissect(&info, 2 * NFSX_UNSIGNED + NFSX_V3WRITEVERF)); rlen = fxdr_unsigned(int, *tl++); if (rlen == 0) { error = NFSERR_IO; - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; break; } else if (rlen < len) { backup = len - rlen; @@ -1358,9 +1381,10 @@ nfs_writerpc(struct vnode *vp, struct uio *uiop, int *iomode, int *must_commit) } } } else { - nfsm_loadattr(vp, NULL); + ERROROUT(nfsm_loadattr(&info, vp, NULL)); } - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; if (error) break; tsiz -= len; @@ -1385,17 +1409,15 @@ nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, { struct nfsv2_sattr *sp; u_int32_t *tl; - caddr_t cp; - int32_t t1, t2; struct vnode *newvp = NULL; struct nfsnode *np = NULL; struct vattr vattr; - char *cp2; - caddr_t bpos, dpos; int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; int rmajor, rminor; - int v3 = NFS_ISV3(dvp); + struct nfsm_info info; + + info.mrep = NULL; + info.v3 = NFS_ISV3(dvp); if (vap->va_type == VCHR || vap->va_type == VBLK) { rmajor = txdr_unsigned(vap->va_rmajor); @@ -1410,21 +1432,23 @@ nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, return (error); } nfsstats.rpccnt[NFSPROC_MKNOD]++; - nfsm_reqhead(dvp, NFSPROC_MKNOD, NFSX_FH(v3) + 4 * NFSX_UNSIGNED + - + nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(v3)); - nfsm_fhtom(dvp, v3); - nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); - if (v3) { - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); + nfsm_reqhead(&info, dvp, NFSPROC_MKNOD, + NFSX_FH(info.v3) + 4 * NFSX_UNSIGNED + + nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(info.v3)); + ERROROUT(nfsm_fhtom(&info, dvp)); + ERROROUT(nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen, + NFS_MAXNAMLEN)); + if (info.v3) { + tl = nfsm_build(&info, NFSX_UNSIGNED); *tl++ = vtonfsv3_type(vap->va_type); - nfsm_v3attrbuild(vap, FALSE); + nfsm_v3attrbuild(&info, vap, FALSE); if (vap->va_type == VCHR || vap->va_type == VBLK) { - nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + tl = nfsm_build(&info, 2 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(vap->va_rmajor); *tl = txdr_unsigned(vap->va_rminor); } } else { - nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR); + sp = nfsm_build(&info, NFSX_V2SATTR); sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode); sp->sa_uid = nfs_xdrneg1; sp->sa_gid = nfs_xdrneg1; @@ -1432,9 +1456,10 @@ nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); } - nfsm_request(dvp, NFSPROC_MKNOD, cnp->cn_td, cnp->cn_cred); + NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_MKNOD, cnp->cn_td, + cnp->cn_cred, &error)); if (!error) { - nfsm_mtofh(dvp, newvp, v3, gotvp); + ERROROUT(nfsm_mtofh(&info, dvp, &newvp, &gotvp)); if (!gotvp) { if (newvp) { vput(newvp); @@ -1446,9 +1471,11 @@ nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, newvp = NFSTOV(np); } } - if (v3) - nfsm_wcc_data(dvp, wccflag); - m_freem(mrep); + if (info.v3) { + ERROROUT(nfsm_wcc_data(&info, dvp, &wccflag)); + } + m_freem(info.mrep); + info.mrep = NULL; nfsmout: if (error) { if (newvp) @@ -1491,15 +1518,14 @@ nfs_create(struct vop_old_create_args *ap) struct componentname *cnp = ap->a_cnp; struct nfsv2_sattr *sp; u_int32_t *tl; - caddr_t cp; - int32_t t1, t2; struct nfsnode *np = NULL; struct vnode *newvp = NULL; - caddr_t bpos, dpos, cp2; int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0, fmode = 0; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; struct vattr vattr; - int v3 = NFS_ISV3(dvp); + struct nfsm_info info; + + info.mrep = NULL; + info.v3 = NFS_ISV3(dvp); /* * Oops, not for me.. @@ -1514,15 +1540,17 @@ nfs_create(struct vop_old_create_args *ap) fmode |= O_EXCL; again: nfsstats.rpccnt[NFSPROC_CREATE]++; - nfsm_reqhead(dvp, NFSPROC_CREATE, NFSX_FH(v3) + 2 * NFSX_UNSIGNED + - nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(v3)); - nfsm_fhtom(dvp, v3); - nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); - if (v3) { - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); + nfsm_reqhead(&info, dvp, NFSPROC_CREATE, + NFSX_FH(info.v3) + 2 * NFSX_UNSIGNED + + nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(info.v3)); + ERROROUT(nfsm_fhtom(&info, dvp)); + ERROROUT(nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen, + NFS_MAXNAMLEN)); + if (info.v3) { + tl = nfsm_build(&info, NFSX_UNSIGNED); if (fmode & O_EXCL) { *tl = txdr_unsigned(NFSV3CREATE_EXCLUSIVE); - nfsm_build(tl, u_int32_t *, NFSX_V3CREATEVERF); + tl = nfsm_build(&info, NFSX_V3CREATEVERF); #ifdef INET if (!TAILQ_EMPTY(&in_ifaddrheads[mycpuid])) *tl++ = IA_SIN(TAILQ_FIRST(&in_ifaddrheads[mycpuid])->ia)->sin_addr.s_addr; @@ -1532,10 +1560,10 @@ again: *tl = ++create_verf; } else { *tl = txdr_unsigned(NFSV3CREATE_UNCHECKED); - nfsm_v3attrbuild(vap, FALSE); + nfsm_v3attrbuild(&info, vap, FALSE); } } else { - nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR); + sp = nfsm_build(&info, NFSX_V2SATTR); sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode); sp->sa_uid = nfs_xdrneg1; sp->sa_gid = nfs_xdrneg1; @@ -1543,9 +1571,10 @@ again: txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); } - nfsm_request(dvp, NFSPROC_CREATE, cnp->cn_td, cnp->cn_cred); - if (!error) { - nfsm_mtofh(dvp, newvp, v3, gotvp); + NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_CREATE, cnp->cn_td, + cnp->cn_cred, &error)); + if (error == 0) { + ERROROUT(nfsm_mtofh(&info, dvp, &newvp, &gotvp)); if (!gotvp) { if (newvp) { vput(newvp); @@ -1557,17 +1586,19 @@ again: newvp = NFSTOV(np); } } - if (v3) - nfsm_wcc_data(dvp, wccflag); - m_freem(mrep); + if (info.v3) { + ERROROUT(nfsm_wcc_data(&info, dvp, &wccflag)); + } + m_freem(info.mrep); + info.mrep = NULL; nfsmout: if (error) { - if (v3 && (fmode & O_EXCL) && error == NFSERR_NOTSUPP) { + if (info.v3 && (fmode & O_EXCL) && error == NFSERR_NOTSUPP) { KKASSERT(newvp == NULL); fmode &= ~O_EXCL; goto again; } - } else if (v3 && (fmode & O_EXCL)) { + } else if (info.v3 && (fmode & O_EXCL)) { /* * We are normally called with only a partially initialized * VAP. Since the NFSv3 spec says that server may use the @@ -1677,23 +1708,23 @@ static int nfs_removerpc(struct vnode *dvp, const char *name, int namelen, struct ucred *cred, struct thread *td) { - u_int32_t *tl; - caddr_t cp; - int32_t t1, t2; - caddr_t bpos, dpos, cp2; int error = 0, wccflag = NFSV3_WCCRATTR; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; - int v3 = NFS_ISV3(dvp); + struct nfsm_info info; + + info.mrep = NULL; + info.v3 = NFS_ISV3(dvp); nfsstats.rpccnt[NFSPROC_REMOVE]++; - nfsm_reqhead(dvp, NFSPROC_REMOVE, - NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(namelen)); - nfsm_fhtom(dvp, v3); - nfsm_strtom(name, namelen, NFS_MAXNAMLEN); - nfsm_request(dvp, NFSPROC_REMOVE, td, cred); - if (v3) - nfsm_wcc_data(dvp, wccflag); - m_freem(mrep); + nfsm_reqhead(&info, dvp, NFSPROC_REMOVE, + NFSX_FH(info.v3) + NFSX_UNSIGNED + nfsm_rndup(namelen)); + ERROROUT(nfsm_fhtom(&info, dvp)); + ERROROUT(nfsm_strtom(&info, name, namelen, NFS_MAXNAMLEN)); + NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_REMOVE, td, cred, &error)); + if (info.v3) { + ERROROUT(nfsm_wcc_data(&info, dvp, &wccflag)); + } + m_freem(info.mrep); + info.mrep = NULL; nfsmout: VTONFS(dvp)->n_flag |= NLMODIFIED; if (!wccflag) @@ -1800,28 +1831,27 @@ nfs_renamerpc(struct vnode *fdvp, const char *fnameptr, int fnamelen, struct vnode *tdvp, const char *tnameptr, int tnamelen, struct ucred *cred, struct thread *td) { - u_int32_t *tl; - caddr_t cp; - int32_t t1, t2; - caddr_t bpos, dpos, cp2; int error = 0, fwccflag = NFSV3_WCCRATTR, twccflag = NFSV3_WCCRATTR; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; - int v3 = NFS_ISV3(fdvp); + struct nfsm_info info; + + info.mrep = NULL; + info.v3 = NFS_ISV3(fdvp); nfsstats.rpccnt[NFSPROC_RENAME]++; - nfsm_reqhead(fdvp, NFSPROC_RENAME, - (NFSX_FH(v3) + NFSX_UNSIGNED)*2 + nfsm_rndup(fnamelen) + - nfsm_rndup(tnamelen)); - nfsm_fhtom(fdvp, v3); - nfsm_strtom(fnameptr, fnamelen, NFS_MAXNAMLEN); - nfsm_fhtom(tdvp, v3); - nfsm_strtom(tnameptr, tnamelen, NFS_MAXNAMLEN); - nfsm_request(fdvp, NFSPROC_RENAME, td, cred); - if (v3) { - nfsm_wcc_data(fdvp, fwccflag); - nfsm_wcc_data(tdvp, twccflag); - } - m_freem(mrep); + nfsm_reqhead(&info, fdvp, NFSPROC_RENAME, + (NFSX_FH(info.v3) + NFSX_UNSIGNED)*2 + + nfsm_rndup(fnamelen) + nfsm_rndup(tnamelen)); + ERROROUT(nfsm_fhtom(&info, fdvp)); + ERROROUT(nfsm_strtom(&info, fnameptr, fnamelen, NFS_MAXNAMLEN)); + ERROROUT(nfsm_fhtom(&info, tdvp)); + ERROROUT(nfsm_strtom(&info, tnameptr, tnamelen, NFS_MAXNAMLEN)); + NEGKEEPOUT(nfsm_request(&info, fdvp, NFSPROC_RENAME, td, cred, &error)); + if (info.v3) { + ERROROUT(nfsm_wcc_data(&info, fdvp, &fwccflag)); + ERROROUT(nfsm_wcc_data(&info, tdvp, &twccflag)); + } + m_freem(info.mrep); + info.mrep = NULL; nfsmout: VTONFS(fdvp)->n_flag |= NLMODIFIED; VTONFS(tdvp)->n_flag |= NLMODIFIED; @@ -1844,13 +1874,8 @@ nfs_link(struct vop_old_link_args *ap) struct vnode *vp = ap->a_vp; struct vnode *tdvp = ap->a_tdvp; struct componentname *cnp = ap->a_cnp; - u_int32_t *tl; - caddr_t cp; - int32_t t1, t2; - caddr_t bpos, dpos, cp2; int error = 0, wccflag = NFSV3_WCCRATTR, attrflag = 0; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; - int v3; + struct nfsm_info info; if (vp->v_mount != tdvp->v_mount) { return (EXDEV); @@ -1865,19 +1890,26 @@ nfs_link(struct vop_old_link_args *ap) if (nfs_flush_on_hlink) VOP_FSYNC(vp, MNT_WAIT); - v3 = NFS_ISV3(vp); + info.mrep = NULL; + info.v3 = NFS_ISV3(vp); + nfsstats.rpccnt[NFSPROC_LINK]++; - nfsm_reqhead(vp, NFSPROC_LINK, - NFSX_FH(v3)*2 + NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen)); - nfsm_fhtom(vp, v3); - nfsm_fhtom(tdvp, v3); - nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); - nfsm_request(vp, NFSPROC_LINK, cnp->cn_td, cnp->cn_cred); - if (v3) { - nfsm_postop_attr(vp, attrflag, NFS_LATTR_NOSHRINK); - nfsm_wcc_data(tdvp, wccflag); - } - m_freem(mrep); + nfsm_reqhead(&info, vp, NFSPROC_LINK, + NFSX_FH(info.v3) * 2 + NFSX_UNSIGNED + + nfsm_rndup(cnp->cn_namelen)); + ERROROUT(nfsm_fhtom(&info, vp)); + ERROROUT(nfsm_fhtom(&info, tdvp)); + ERROROUT(nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen, + NFS_MAXNAMLEN)); + NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_LINK, cnp->cn_td, + cnp->cn_cred, &error)); + if (info.v3) { + ERROROUT(nfsm_postop_attr(&info, vp, &attrflag, + NFS_LATTR_NOSHRINK)); + ERROROUT(nfsm_wcc_data(&info, tdvp, &wccflag)); + } + m_freem(info.mrep); + info.mrep = NULL; nfsmout: VTONFS(tdvp)->n_flag |= NLMODIFIED; if (!attrflag) @@ -1906,27 +1938,28 @@ nfs_symlink(struct vop_old_symlink_args *ap) struct vattr *vap = ap->a_vap; struct componentname *cnp = ap->a_cnp; struct nfsv2_sattr *sp; - u_int32_t *tl; - caddr_t cp; - int32_t t1, t2; - caddr_t bpos, dpos, cp2; int slen, error = 0, wccflag = NFSV3_WCCRATTR, gotvp; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; struct vnode *newvp = NULL; - int v3 = NFS_ISV3(dvp); + struct nfsm_info info; + + info.mrep = NULL; + info.v3 = NFS_ISV3(dvp); nfsstats.rpccnt[NFSPROC_SYMLINK]++; slen = strlen(ap->a_target); - nfsm_reqhead(dvp, NFSPROC_SYMLINK, NFSX_FH(v3) + 2*NFSX_UNSIGNED + - nfsm_rndup(cnp->cn_namelen) + nfsm_rndup(slen) + NFSX_SATTR(v3)); - nfsm_fhtom(dvp, v3); - nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); - if (v3) { - nfsm_v3attrbuild(vap, FALSE); - } - nfsm_strtom(ap->a_target, slen, NFS_MAXPATHLEN); - if (!v3) { - nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR); + nfsm_reqhead(&info, dvp, NFSPROC_SYMLINK, + NFSX_FH(info.v3) + 2*NFSX_UNSIGNED + + nfsm_rndup(cnp->cn_namelen) + + nfsm_rndup(slen) + NFSX_SATTR(info.v3)); + ERROROUT(nfsm_fhtom(&info, dvp)); + ERROROUT(nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen, + NFS_MAXNAMLEN)); + if (info.v3) { + nfsm_v3attrbuild(&info, vap, FALSE); + } + ERROROUT(nfsm_strtom(&info, ap->a_target, slen, NFS_MAXPATHLEN)); + if (info.v3 == 0) { + sp = nfsm_build(&info, NFSX_V2SATTR); sp->sa_mode = vtonfsv2_mode(VLNK, vap->va_mode); sp->sa_uid = nfs_xdrneg1; sp->sa_gid = nfs_xdrneg1; @@ -1942,18 +1975,21 @@ nfs_symlink(struct vop_old_symlink_args *ap) * a file handle that can be converted into newvp without having * to do an extra lookup rpc. */ - nfsm_request(dvp, NFSPROC_SYMLINK, cnp->cn_td, cnp->cn_cred); - if (v3) { - if (error == 0) - nfsm_mtofh(dvp, newvp, v3, gotvp); - nfsm_wcc_data(dvp, wccflag); + NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_SYMLINK, cnp->cn_td, + cnp->cn_cred, &error)); + if (info.v3) { + if (error == 0) { + ERROROUT(nfsm_mtofh(&info, dvp, &newvp, &gotvp)); + } + ERROROUT(nfsm_wcc_data(&info, dvp, &wccflag)); } /* * out code jumps -> here, mrep is also freed. */ - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; nfsmout: /* @@ -2002,32 +2038,31 @@ nfs_mkdir(struct vop_old_mkdir_args *ap) struct vattr *vap = ap->a_vap; struct componentname *cnp = ap->a_cnp; struct nfsv2_sattr *sp; - u_int32_t *tl; - caddr_t cp; - int32_t t1, t2; - int len; struct nfsnode *np = NULL; struct vnode *newvp = NULL; - caddr_t bpos, dpos, cp2; + struct vattr vattr; int error = 0, wccflag = NFSV3_WCCRATTR; int gotvp = 0; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; - struct vattr vattr; - int v3 = NFS_ISV3(dvp); + int len; + struct nfsm_info info; + + info.mrep = NULL; + info.v3 = NFS_ISV3(dvp); if ((error = VOP_GETATTR(dvp, &vattr)) != 0) { return (error); } len = cnp->cn_namelen; nfsstats.rpccnt[NFSPROC_MKDIR]++; - nfsm_reqhead(dvp, NFSPROC_MKDIR, - NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len) + NFSX_SATTR(v3)); - nfsm_fhtom(dvp, v3); - nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN); - if (v3) { - nfsm_v3attrbuild(vap, FALSE); + nfsm_reqhead(&info, dvp, NFSPROC_MKDIR, + NFSX_FH(info.v3) + NFSX_UNSIGNED + + nfsm_rndup(len) + NFSX_SATTR(info.v3)); + ERROROUT(nfsm_fhtom(&info, dvp)); + ERROROUT(nfsm_strtom(&info, cnp->cn_nameptr, len, NFS_MAXNAMLEN)); + if (info.v3) { + nfsm_v3attrbuild(&info, vap, FALSE); } else { - nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR); + sp = nfsm_build(&info, NFSX_V2SATTR); sp->sa_mode = vtonfsv2_mode(VDIR, vap->va_mode); sp->sa_uid = nfs_xdrneg1; sp->sa_gid = nfs_xdrneg1; @@ -2035,12 +2070,16 @@ nfs_mkdir(struct vop_old_mkdir_args *ap) txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); } - nfsm_request(dvp, NFSPROC_MKDIR, cnp->cn_td, cnp->cn_cred); - if (!error) - nfsm_mtofh(dvp, newvp, v3, gotvp); - if (v3) - nfsm_wcc_data(dvp, wccflag); - m_freem(mrep); + NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_MKDIR, cnp->cn_td, + cnp->cn_cred, &error)); + if (error == 0) { + ERROROUT(nfsm_mtofh(&info, dvp, &newvp, &gotvp)); + } + if (info.v3) { + ERROROUT(nfsm_wcc_data(&info, dvp, &wccflag)); + } + m_freem(info.mrep); + info.mrep = NULL; nfsmout: VTONFS(dvp)->n_flag |= NLMODIFIED; if (!wccflag) @@ -2082,25 +2121,28 @@ nfs_rmdir(struct vop_old_rmdir_args *ap) struct vnode *vp = ap->a_vp; struct vnode *dvp = ap->a_dvp; struct componentname *cnp = ap->a_cnp; - u_int32_t *tl; - caddr_t cp; - int32_t t1, t2; - caddr_t bpos, dpos, cp2; int error = 0, wccflag = NFSV3_WCCRATTR; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; - int v3 = NFS_ISV3(dvp); + struct nfsm_info info; + + info.mrep = NULL; + info.v3 = NFS_ISV3(dvp); if (dvp == vp) return (EINVAL); nfsstats.rpccnt[NFSPROC_RMDIR]++; - nfsm_reqhead(dvp, NFSPROC_RMDIR, - NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen)); - nfsm_fhtom(dvp, v3); - nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); - nfsm_request(dvp, NFSPROC_RMDIR, cnp->cn_td, cnp->cn_cred); - if (v3) - nfsm_wcc_data(dvp, wccflag); - m_freem(mrep); + nfsm_reqhead(&info, dvp, NFSPROC_RMDIR, + NFSX_FH(info.v3) + NFSX_UNSIGNED + + nfsm_rndup(cnp->cn_namelen)); + ERROROUT(nfsm_fhtom(&info, dvp)); + ERROROUT(nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen, + NFS_MAXNAMLEN)); + NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_RMDIR, cnp->cn_td, + cnp->cn_cred, &error)); + if (info.v3) { + ERROROUT(nfsm_wcc_data(&info, dvp, &wccflag)); + } + m_freem(info.mrep); + info.mrep = NULL; nfsmout: VTONFS(dvp)->n_flag |= NLMODIFIED; if (!wccflag) @@ -2178,18 +2220,18 @@ nfs_readdirrpc(struct vnode *vp, struct uio *uiop) int len, left; struct nfs_dirent *dp = NULL; u_int32_t *tl; - caddr_t cp; - int32_t t1, t2; nfsuint64 *cookiep; - caddr_t bpos, dpos, cp2; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; + caddr_t cp; nfsuint64 cookie; struct nfsmount *nmp = VFSTONFS(vp->v_mount); struct nfsnode *dnp = VTONFS(vp); u_quad_t fileno; int error = 0, tlen, more_dirs = 1, blksiz = 0, bigenough = 1; int attrflag; - int v3 = NFS_ISV3(vp); + struct nfsm_info info; + + info.mrep = NULL; + info.v3 = NFS_ISV3(vp); #ifndef DIAGNOSTIC if (uiop->uio_iovcnt != 1 || (uiop->uio_offset & (DIRBLKSIZ - 1)) || @@ -2212,52 +2254,48 @@ nfs_readdirrpc(struct vnode *vp, struct uio *uiop) */ while (more_dirs && bigenough) { nfsstats.rpccnt[NFSPROC_READDIR]++; - nfsm_reqhead(vp, NFSPROC_READDIR, NFSX_FH(v3) + - NFSX_READDIR(v3)); - nfsm_fhtom(vp, v3); - if (v3) { - nfsm_build(tl, u_int32_t *, 5 * NFSX_UNSIGNED); + nfsm_reqhead(&info, vp, NFSPROC_READDIR, + NFSX_FH(info.v3) + NFSX_READDIR(info.v3)); + ERROROUT(nfsm_fhtom(&info, vp)); + if (info.v3) { + tl = nfsm_build(&info, 5 * NFSX_UNSIGNED); *tl++ = cookie.nfsuquad[0]; *tl++ = cookie.nfsuquad[1]; *tl++ = dnp->n_cookieverf.nfsuquad[0]; *tl++ = dnp->n_cookieverf.nfsuquad[1]; } else { - nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + tl = nfsm_build(&info, 2 * NFSX_UNSIGNED); *tl++ = cookie.nfsuquad[0]; } *tl = txdr_unsigned(nmp->nm_readdirsize); - nfsm_request(vp, NFSPROC_READDIR, uiop->uio_td, nfs_vpcred(vp, ND_READ)); - if (v3) { - nfsm_postop_attr(vp, attrflag, NFS_LATTR_NOSHRINK); - if (!error) { - nfsm_dissect(tl, u_int32_t *, - 2 * NFSX_UNSIGNED); - dnp->n_cookieverf.nfsuquad[0] = *tl++; - dnp->n_cookieverf.nfsuquad[1] = *tl; - } else { - m_freem(mrep); - goto nfsmout; - } + NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_READDIR, + uiop->uio_td, + nfs_vpcred(vp, ND_READ), &error)); + if (info.v3) { + ERROROUT(nfsm_postop_attr(&info, vp, &attrflag, + NFS_LATTR_NOSHRINK)); + NULLOUT(tl = nfsm_dissect(&info, 2 * NFSX_UNSIGNED)); + dnp->n_cookieverf.nfsuquad[0] = *tl++; + dnp->n_cookieverf.nfsuquad[1] = *tl; } - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED)); more_dirs = fxdr_unsigned(int, *tl); /* loop thru the dir entries, converting them to std form */ while (more_dirs && bigenough) { - if (v3) { - nfsm_dissect(tl, u_int32_t *, - 3 * NFSX_UNSIGNED); + if (info.v3) { + NULLOUT(tl = nfsm_dissect(&info, 3 * NFSX_UNSIGNED)); fileno = fxdr_hyper(tl); len = fxdr_unsigned(int, *(tl + 2)); } else { - nfsm_dissect(tl, u_int32_t *, - 2 * NFSX_UNSIGNED); + NULLOUT(tl = nfsm_dissect(&info, 2 * NFSX_UNSIGNED)); fileno = fxdr_unsigned(u_quad_t, *tl++); len = fxdr_unsigned(int, *tl); } if (len <= 0 || len > NFS_MAXNAMLEN) { error = EBADRPC; - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; goto nfsmout; } @@ -2301,7 +2339,7 @@ nfs_readdirrpc(struct vnode *vp, struct uio *uiop) uiop->uio_resid -= sizeof(struct nfs_dirent); uiop->uio_iov->iov_base = (char *)uiop->uio_iov->iov_base + sizeof(struct nfs_dirent); uiop->uio_iov->iov_len -= sizeof(struct nfs_dirent); - nfsm_mtouio(uiop, len); + ERROROUT(nfsm_mtouio(&info, uiop, len)); /* * The uiop has advanced by nfs_dirent + len @@ -2320,14 +2358,12 @@ nfs_readdirrpc(struct vnode *vp, struct uio *uiop) * NFS strings must be rounded up (nfsm_myouio * handled that in the bigenough case). */ - nfsm_adv(nfsm_rndup(len)); + ERROROUT(nfsm_adv(&info, nfsm_rndup(len))); } - if (v3) { - nfsm_dissect(tl, u_int32_t *, - 3 * NFSX_UNSIGNED); + if (info.v3) { + NULLOUT(tl = nfsm_dissect(&info, 3 * NFSX_UNSIGNED)); } else { - nfsm_dissect(tl, u_int32_t *, - 2 * NFSX_UNSIGNED); + NULLOUT(tl = nfsm_dissect(&info, 2 * NFSX_UNSIGNED)); } /* @@ -2338,9 +2374,9 @@ nfs_readdirrpc(struct vnode *vp, struct uio *uiop) */ if (bigenough) { cookie.nfsuquad[0] = *tl++; - if (v3) + if (info.v3) cookie.nfsuquad[1] = *tl++; - } else if (v3) { + } else if (info.v3) { tl += 2; } else { tl++; @@ -2351,10 +2387,11 @@ nfs_readdirrpc(struct vnode *vp, struct uio *uiop) * If at end of rpc data, get the eof boolean */ if (!more_dirs) { - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED)); more_dirs = (fxdr_unsigned(int, *tl) == 0); } - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; } /* * Fill last record, iff any, out to a multiple of DIRBLKSIZ @@ -2397,12 +2434,11 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop) int len, left; struct nfs_dirent *dp; u_int32_t *tl; - caddr_t cp; - int32_t t1, t2; struct vnode *newvp; nfsuint64 *cookiep; - caddr_t bpos, dpos, cp2, dpossav1, dpossav2; - struct mbuf *mreq, *mrep, *md, *mb, *mb2, *mdsav1, *mdsav2; + caddr_t dpossav1, dpossav2; + caddr_t cp; + struct mbuf *mdsav1, *mdsav2; nfsuint64 cookie; struct nfsmount *nmp = VFSTONFS(vp->v_mount); struct nfsnode *dnp = VTONFS(vp), *np; @@ -2413,6 +2449,10 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop) struct nchandle nch; struct nchandle dnch; struct nlcomponent nlc; + struct nfsm_info info; + + info.mrep = NULL; + info.v3 = 1; #ifndef nolint dp = NULL; @@ -2449,35 +2489,35 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop) */ while (more_dirs && bigenough) { nfsstats.rpccnt[NFSPROC_READDIRPLUS]++; - nfsm_reqhead(vp, NFSPROC_READDIRPLUS, - NFSX_FH(1) + 6 * NFSX_UNSIGNED); - nfsm_fhtom(vp, 1); - nfsm_build(tl, u_int32_t *, 6 * NFSX_UNSIGNED); + nfsm_reqhead(&info, vp, NFSPROC_READDIRPLUS, + NFSX_FH(1) + 6 * NFSX_UNSIGNED); + ERROROUT(nfsm_fhtom(&info, vp)); + tl = nfsm_build(&info, 6 * NFSX_UNSIGNED); *tl++ = cookie.nfsuquad[0]; *tl++ = cookie.nfsuquad[1]; *tl++ = dnp->n_cookieverf.nfsuquad[0]; *tl++ = dnp->n_cookieverf.nfsuquad[1]; *tl++ = txdr_unsigned(nmp->nm_readdirsize); *tl = txdr_unsigned(nmp->nm_rsize); - nfsm_request(vp, NFSPROC_READDIRPLUS, uiop->uio_td, nfs_vpcred(vp, ND_READ)); - nfsm_postop_attr(vp, attrflag, NFS_LATTR_NOSHRINK); - if (error) { - m_freem(mrep); - goto nfsmout; - } - nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED); + NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_READDIRPLUS, + uiop->uio_td, + nfs_vpcred(vp, ND_READ), &error)); + ERROROUT(nfsm_postop_attr(&info, vp, &attrflag, + NFS_LATTR_NOSHRINK)); + NULLOUT(tl = nfsm_dissect(&info, 3 * NFSX_UNSIGNED)); 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); + NULLOUT(tl = nfsm_dissect(&info, 3 * NFSX_UNSIGNED)); fileno = fxdr_hyper(tl); len = fxdr_unsigned(int, *(tl + 2)); if (len <= 0 || len > NFS_MAXNAMLEN) { error = EBADRPC; - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; goto nfsmout; } tlen = nfsm_rndup(len); @@ -2509,7 +2549,7 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop) uiop->uio_iov->iov_len -= sizeof(struct nfs_dirent); nlc.nlc_nameptr = uiop->uio_iov->iov_base; nlc.nlc_namelen = len; - nfsm_mtouio(uiop, len); + ERROROUT(nfsm_mtouio(&info, uiop, len)); cp = uiop->uio_iov->iov_base; tlen -= len; *cp = '\0'; @@ -2517,9 +2557,10 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop) uiop->uio_iov->iov_len -= tlen; uiop->uio_offset += tlen; uiop->uio_resid -= tlen; - } else - nfsm_adv(nfsm_rndup(len)); - nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED); + } else { + ERROROUT(nfsm_adv(&info, nfsm_rndup(len))); + } + NULLOUT(tl = nfsm_dissect(&info, 3 * NFSX_UNSIGNED)); if (bigenough) { cookie.nfsuquad[0] = *tl++; cookie.nfsuquad[1] = *tl++; @@ -2533,13 +2574,13 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop) */ attrflag = fxdr_unsigned(int, *tl); if (attrflag) { - dpossav1 = dpos; - mdsav1 = md; - nfsm_adv(NFSX_V3FATTR); - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + dpossav1 = info.dpos; + mdsav1 = info.md; + ERROROUT(nfsm_adv(&info, NFSX_V3FATTR)); + NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED)); doit = fxdr_unsigned(int, *tl); if (doit) { - nfsm_getfh(fhp, fhsize, 1); + NEGATIVEOUT(fhsize = nfsm_getfh(&info, &fhp)); if (NFS_CMPFH(dnp, fhp, fhsize)) { vref(vp); newvp = vp; @@ -2554,13 +2595,13 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop) } } if (doit && bigenough) { - dpossav2 = dpos; - dpos = dpossav1; - mdsav2 = md; - md = mdsav1; - nfsm_loadattr(newvp, NULL); - dpos = dpossav2; - md = mdsav2; + dpossav2 = info.dpos; + info.dpos = dpossav1; + mdsav2 = info.md; + info.md = mdsav1; + ERROROUT(nfsm_loadattr(&info, newvp, NULL)); + info.dpos = dpossav2; + info.md = mdsav2; dp->nfs_type = IFTODT(VTTOIF(np->n_vattr.va_type)); if (dnch.ncp) { @@ -2581,9 +2622,9 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop) } } else { /* Just skip over the file handle */ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED)); i = fxdr_unsigned(int, *tl); - nfsm_adv(nfsm_rndup(i)); + ERROROUT(nfsm_adv(&info, nfsm_rndup(i))); } if (newvp != NULLVP) { if (newvp == vp) @@ -2592,17 +2633,18 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop) vput(newvp); newvp = NULLVP; } - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED)); 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); + NULLOUT(tl = nfsm_dissect(&info, NFSX_UNSIGNED)); more_dirs = (fxdr_unsigned(int, *tl) == 0); } - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; } /* * Fill last record, iff any, out to a multiple of DIRBLKSIZ @@ -2713,25 +2755,23 @@ static int nfs_lookitup(struct vnode *dvp, const char *name, int len, struct ucred *cred, struct thread *td, struct nfsnode **npp) { - u_int32_t *tl; - caddr_t cp; - int32_t t1, t2; struct vnode *newvp = NULL; struct nfsnode *np, *dnp = VTONFS(dvp); - caddr_t bpos, dpos, cp2; int error = 0, fhlen, attrflag; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; nfsfh_t *nfhp; - int v3 = NFS_ISV3(dvp); + struct nfsm_info info; + + info.mrep = NULL; + info.v3 = NFS_ISV3(dvp); nfsstats.rpccnt[NFSPROC_LOOKUP]++; - nfsm_reqhead(dvp, NFSPROC_LOOKUP, - NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len)); - nfsm_fhtom(dvp, v3); - nfsm_strtom(name, len, NFS_MAXNAMLEN); - nfsm_request(dvp, NFSPROC_LOOKUP, td, cred); + nfsm_reqhead(&info, dvp, NFSPROC_LOOKUP, + NFSX_FH(info.v3) + NFSX_UNSIGNED + nfsm_rndup(len)); + ERROROUT(nfsm_fhtom(&info, dvp)); + ERROROUT(nfsm_strtom(&info, name, len, NFS_MAXNAMLEN)); + NEGKEEPOUT(nfsm_request(&info, dvp, NFSPROC_LOOKUP, td, cred, &error)); if (npp && !error) { - nfsm_getfh(nfhp, fhlen, v3); + NEGATIVEOUT(fhlen = nfsm_getfh(&info, &nfhp)); if (*npp) { np = *npp; if (np->n_fhsize > NFS_SMALLFH && fhlen <= NFS_SMALLFH) { @@ -2748,25 +2788,30 @@ nfs_lookitup(struct vnode *dvp, const char *name, int len, struct ucred *cred, } else { error = nfs_nget(dvp->v_mount, nfhp, fhlen, &np); if (error) { - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; return (error); } newvp = NFSTOV(np); } - if (v3) { - nfsm_postop_attr(newvp, attrflag, NFS_LATTR_NOSHRINK); + if (info.v3) { + ERROROUT(nfsm_postop_attr(&info, newvp, &attrflag, + NFS_LATTR_NOSHRINK)); if (!attrflag && *npp == NULL) { - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; if (newvp == dvp) vrele(newvp); else vput(newvp); return (ENOENT); } - } else - nfsm_loadattr(newvp, NULL); + } else { + ERROROUT(error = nfsm_loadattr(&info, newvp, NULL)); + } } - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; nfsmout: if (npp && *npp == NULL) { if (error) { @@ -2788,27 +2833,28 @@ nfsmout: int nfs_commit(struct vnode *vp, u_quad_t offset, int cnt, struct thread *td) { - caddr_t cp; - u_int32_t *tl; - int32_t t1, t2; struct nfsmount *nmp = VFSTONFS(vp->v_mount); - caddr_t bpos, dpos, cp2; int error = 0, wccflag = NFSV3_WCCRATTR; - struct mbuf *mreq, *mrep, *md, *mb, *mb2; + struct nfsm_info info; + u_int32_t *tl; + + info.mrep = NULL; + info.v3 = 1; if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0) return (0); nfsstats.rpccnt[NFSPROC_COMMIT]++; - nfsm_reqhead(vp, NFSPROC_COMMIT, NFSX_FH(1)); - nfsm_fhtom(vp, 1); - nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED); + nfsm_reqhead(&info, vp, NFSPROC_COMMIT, NFSX_FH(1)); + ERROROUT(nfsm_fhtom(&info, vp)); + tl = nfsm_build(&info, 3 * NFSX_UNSIGNED); txdr_hyper(offset, tl); tl += 2; *tl = txdr_unsigned(cnt); - nfsm_request(vp, NFSPROC_COMMIT, td, nfs_vpcred(vp, ND_WRITE)); - nfsm_wcc_data(vp, wccflag); + NEGKEEPOUT(nfsm_request(&info, vp, NFSPROC_COMMIT, td, + nfs_vpcred(vp, ND_WRITE), &error)); + ERROROUT(nfsm_wcc_data(&info, vp, &wccflag)); if (!error) { - nfsm_dissect(tl, u_int32_t *, NFSX_V3WRITEVERF); + NULLOUT(tl = nfsm_dissect(&info, NFSX_V3WRITEVERF)); if (bcmp((caddr_t)nmp->nm_verf, (caddr_t)tl, NFSX_V3WRITEVERF)) { bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf, @@ -2816,7 +2862,8 @@ nfs_commit(struct vnode *vp, u_quad_t offset, int cnt, struct thread *td) error = NFSERR_STALEWRITEVERF; } } - m_freem(mrep); + m_freem(info.mrep); + info.mrep = NULL; nfsmout: return (error); } diff --git a/sys/vfs/nfs/nfsm_subs.c b/sys/vfs/nfs/nfsm_subs.c index 7e803c3f2b..31e9b33c38 100644 --- a/sys/vfs/nfs/nfsm_subs.c +++ b/sys/vfs/nfs/nfsm_subs.c @@ -115,19 +115,13 @@ static u_int32_t nfs_xid = 0; * The hsiz is the size of the rest of the nfs request header. * (just used to decide if a cluster is a good idea) */ -struct mbuf * -nfsm_reqh(struct vnode *vp, u_long procid, int hsiz, caddr_t *bposp) +void +nfsm_reqhead(nfsm_info_t info, struct vnode *vp, u_long procid, int hsiz) { - struct mbuf *mb; - caddr_t bpos; - - mb = m_getl(hsiz, MB_WAIT, MT_DATA, 0, NULL); - mb->m_len = 0; - bpos = mtod(mb, caddr_t); - - /* Finally, return values */ - *bposp = bpos; - return (mb); + info->mb = m_getl(hsiz, MB_WAIT, MT_DATA, 0, NULL); + info->mb->m_len = 0; + info->mreq = info->mb; + info->bpos = mtod(info->mb, caddr_t); } /* @@ -142,30 +136,28 @@ nfsm_rpchead(struct ucred *cr, int nmflag, int procid, int auth_type, struct mbuf *mrest, int mrest_len, struct mbuf **mbp, u_int32_t *xidp) { - struct mbuf *mb; + struct nfsm_info info; u_int32_t *tl; - caddr_t bpos; - int i; - struct mbuf *mreq, *mb2; int siz, grpsiz, authsiz, dsiz; + int i; authsiz = nfsm_rndup(auth_len); dsiz = authsiz + 10 * NFSX_UNSIGNED; - mb = m_getl(dsiz, MB_WAIT, MT_DATA, M_PKTHDR, NULL); + info.mb = m_getl(dsiz, MB_WAIT, MT_DATA, M_PKTHDR, NULL); if (dsiz < MINCLSIZE) { if (dsiz < MHLEN) - MH_ALIGN(mb, dsiz); + MH_ALIGN(info.mb, dsiz); else - MH_ALIGN(mb, 8 * NFSX_UNSIGNED); + MH_ALIGN(info.mb, 8 * NFSX_UNSIGNED); } - mb->m_len = mb->m_pkthdr.len = 0; - mreq = mb; - bpos = mtod(mb, caddr_t); + info.mb->m_len = info.mb->m_pkthdr.len = 0; + info.mreq = info.mb; + info.bpos = mtod(info.mb, caddr_t); /* * First the RPC header. */ - nfsm_build(tl, u_int32_t *, 8 * NFSX_UNSIGNED); + tl = nfsm_build(&info, 8 * NFSX_UNSIGNED); /* Get a pretty random xid to start with */ if (!nfs_xid) @@ -196,7 +188,7 @@ nfsm_rpchead(struct ucred *cr, int nmflag, int procid, int auth_type, *tl = txdr_unsigned(authsiz); switch (auth_type) { case RPCAUTH_UNIX: - nfsm_build(tl, u_int32_t *, auth_len); + tl = nfsm_build(&info, auth_len); *tl++ = 0; /* stamp ?? */ *tl++ = 0; /* NULL hostname */ *tl++ = txdr_unsigned(cr->cr_uid); @@ -209,24 +201,24 @@ nfsm_rpchead(struct ucred *cr, int nmflag, int procid, int auth_type, case RPCAUTH_KERB4: siz = auth_len; while (siz > 0) { - if (M_TRAILINGSPACE(mb) == 0) { - mb2 = m_getl(siz, MB_WAIT, MT_DATA, 0, NULL); - mb2->m_len = 0; - mb->m_next = mb2; - mb = mb2; - bpos = mtod(mb, caddr_t); + if (M_TRAILINGSPACE(info.mb) == 0) { + info.mb2 = m_getl(siz, MB_WAIT, MT_DATA, 0, NULL); + info.mb2->m_len = 0; + info.mb->m_next = info.mb2; + info.mb = info.mb2; + info.bpos = mtod(info.mb, caddr_t); } - i = min(siz, M_TRAILINGSPACE(mb)); - bcopy(auth_str, bpos, i); - mb->m_len += i; + i = min(siz, M_TRAILINGSPACE(info.mb)); + bcopy(auth_str, info.bpos, i); + info.mb->m_len += i; auth_str += i; - bpos += i; + info.bpos += i; siz -= i; } if ((siz = (nfsm_rndup(auth_len) - auth_len)) > 0) { for (i = 0; i < siz; i++) - *bpos++ = '\0'; - mb->m_len += siz; + *info.bpos++ = '\0'; + info.mb->m_len += siz; } break; }; @@ -234,40 +226,721 @@ nfsm_rpchead(struct ucred *cr, int nmflag, int procid, int auth_type, /* * And the verifier... */ - nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + tl = nfsm_build(&info, 2 * NFSX_UNSIGNED); if (verf_str) { *tl++ = txdr_unsigned(RPCAUTH_KERB4); *tl = txdr_unsigned(verf_len); siz = verf_len; while (siz > 0) { - if (M_TRAILINGSPACE(mb) == 0) { - mb2 = m_getl(siz, MB_WAIT, MT_DATA, 0, NULL); - mb2->m_len = 0; - mb->m_next = mb2; - mb = mb2; - bpos = mtod(mb, caddr_t); + if (M_TRAILINGSPACE(info.mb) == 0) { + info.mb2 = m_getl(siz, MB_WAIT, MT_DATA, + 0, NULL); + info.mb2->m_len = 0; + info.mb->m_next = info.mb2; + info.mb = info.mb2; + info.bpos = mtod(info.mb, caddr_t); } - i = min(siz, M_TRAILINGSPACE(mb)); - bcopy(verf_str, bpos, i); - mb->m_len += i; + i = min(siz, M_TRAILINGSPACE(info.mb)); + bcopy(verf_str, info.bpos, i); + info.mb->m_len += i; verf_str += i; - bpos += i; + info.bpos += i; siz -= i; } if ((siz = (nfsm_rndup(verf_len) - verf_len)) > 0) { for (i = 0; i < siz; i++) - *bpos++ = '\0'; - mb->m_len += siz; + *info.bpos++ = '\0'; + info.mb->m_len += siz; } } else { *tl++ = txdr_unsigned(RPCAUTH_NULL); *tl = 0; } - mb->m_next = mrest; - mreq->m_pkthdr.len = authsiz + 10 * NFSX_UNSIGNED + mrest_len; - mreq->m_pkthdr.rcvif = NULL; - *mbp = mb; - return (mreq); + info.mb->m_next = mrest; + info.mreq->m_pkthdr.len = authsiz + 10 * NFSX_UNSIGNED + mrest_len; + info.mreq->m_pkthdr.rcvif = NULL; + *mbp = info.mb; + return (info.mreq); +} + +void * +nfsm_build(nfsm_info_t info, int bytes) +{ + void *ptr; + + if (bytes > M_TRAILINGSPACE(info->mb)) { + MGET(info->mb2, MB_WAIT, MT_DATA); + if (bytes > MLEN) + panic("build > MLEN"); + info->mb->m_next = info->mb2; + info->mb = info->mb2; + info->mb->m_len = 0; + info->bpos = mtod(info->mb, caddr_t); + } + ptr = info->bpos; + info->mb->m_len += bytes; + info->bpos += bytes; + return (ptr); +} + +/* + * + * If NULL returned caller is expected to abort with an EBADRPC error. + * Caller will usually use the NULLOUT macro. + */ +void * +nfsm_dissect(nfsm_info_t info, int bytes) +{ + caddr_t cp2; + void *ptr; + int error; + int n; + + n = mtod(info->md, caddr_t) + info->md->m_len - info->dpos; + if (bytes <= n) { + ptr = info->dpos; + info->dpos += bytes; + } else { + error = nfsm_disct(&info->md, &info->dpos, bytes, n, &cp2); + if (error) { + m_freem(info->mrep); + info->mrep = NULL; + ptr = NULL; + } else { + ptr = cp2; + } + } + return (ptr); +} + +/* + * + * Caller is expected to abort if non-zero error is returned. + */ +int +nfsm_fhtom(nfsm_info_t info, struct vnode *vp) +{ + u_int32_t *tl; + caddr_t cp; + int error; + int n; + + if (info->v3) { + n = nfsm_rndup(VTONFS(vp)->n_fhsize) + NFSX_UNSIGNED; + if (n <= M_TRAILINGSPACE(info->mb)) { + tl = nfsm_build(info, n); + *tl++ = txdr_unsigned(VTONFS(vp)->n_fhsize); + *(tl + ((n >> 2) - 2)) = 0; + bcopy((caddr_t)VTONFS(vp)->n_fhp,(caddr_t)tl, + VTONFS(vp)->n_fhsize); + error = 0; + } else if ((error = nfsm_strtmbuf(&info->mb, &info->bpos, + (caddr_t)VTONFS(vp)->n_fhp, + VTONFS(vp)->n_fhsize)) != 0) { + m_freem(info->mreq); + info->mreq = NULL; + } + } else { + cp = nfsm_build(info, NFSX_V2FH); + bcopy(VTONFS(vp)->n_fhp, cp, NFSX_V2FH); + error = 0; + } + return (error); +} + +void +nfsm_srvfhtom(nfsm_info_t info, fhandle_t *fhp) +{ + u_int32_t *tl; + + if (info->v3) { + tl = nfsm_build(info, NFSX_UNSIGNED + NFSX_V3FH); + *tl++ = txdr_unsigned(NFSX_V3FH); + bcopy(fhp, tl, NFSX_V3FH); + } else { + tl = nfsm_build(info, NFSX_V2FH); + bcopy(fhp, tl, NFSX_V2FH); + } +} + +void +nfsm_srvpostop_fh(nfsm_info_t info, fhandle_t *fhp) +{ + u_int32_t *tl; + + tl = nfsm_build(info, 2 * NFSX_UNSIGNED + NFSX_V3FH); + *tl++ = nfs_true; + *tl++ = txdr_unsigned(NFSX_V3FH); + bcopy(fhp, tl, NFSX_V3FH); +} + +/* + * Caller is expected to abort if non-zero error is returned. + * + * NOTE: (*vpp) may be loaded with a valid vnode even if (*gotvpp) + * winds up 0. The caller is responsible for dealing with (*vpp). + */ +int +nfsm_mtofh(nfsm_info_t info, struct vnode *dvp, struct vnode **vpp, int *gotvpp) +{ + struct nfsnode *ttnp; + nfsfh_t *ttfhp; + u_int32_t *tl; + int ttfhsize; + int error = 0; + + if (info->v3) { + tl = nfsm_dissect(info, NFSX_UNSIGNED); + if (tl == NULL) + return(EBADRPC); + *gotvpp = fxdr_unsigned(int, *tl); + } else { + *gotvpp = 1; + } + if (*gotvpp) { + NEGATIVEOUT(ttfhsize = nfsm_getfh(info, &ttfhp)); + error = nfs_nget(dvp->v_mount, ttfhp, ttfhsize, &ttnp); + if (error) { + m_freem(info->mrep); + info->mrep = NULL; + return (error); + } + *vpp = NFSTOV(ttnp); + } + if (info->v3) { + tl = nfsm_dissect(info, NFSX_UNSIGNED); + if (tl == NULL) + return (EBADRPC); + if (*gotvpp) { + *gotvpp = fxdr_unsigned(int, *tl); + } else if (fxdr_unsigned(int, *tl)) { + error = nfsm_adv(info, NFSX_V3FATTR); + if (error) + return (error); + } + } + if (*gotvpp) + error = nfsm_loadattr(info, *vpp, NULL); +nfsmout: + return (error); +} + +/* + * + * Caller is expected to abort with EBADRPC if a negative length is returned. + */ +int +nfsm_getfh(nfsm_info_t info, nfsfh_t **fhpp) +{ + u_int32_t *tl; + int n; + + *fhpp = NULL; + if (info->v3) { + tl = nfsm_dissect(info, NFSX_UNSIGNED); + if (tl == NULL) + return(-1); + if ((n = fxdr_unsigned(int, *tl)) <= 0 || n > NFSX_V3FHMAX) { + m_freem(info->mrep); + info->mrep = NULL; + return(-1); + } + } else { + n = NFSX_V2FH; + } + *fhpp = nfsm_dissect(info, nfsm_rndup(n)); + if (*fhpp == NULL) + return(-1); + return(n); +} + +/* + * Caller is expected to abort if a non-zero error is returned. + */ +int +nfsm_loadattr(nfsm_info_t info, struct vnode *vp, struct vattr *vap) +{ + int error; + + error = nfs_loadattrcache(vp, &info->md, &info->dpos, vap, 0); + if (error) { + m_freem(info->mrep); + info->mrep = NULL; + return (error); + } + return (0); +} + +/* + * Caller is expected to abort if a non-zero error is returned. + */ +int +nfsm_postop_attr(nfsm_info_t info, struct vnode *vp, int *attrp, int lflags) +{ + u_int32_t *tl; + int error; + + tl = nfsm_dissect(info, NFSX_UNSIGNED); + if (tl == NULL) + return(EBADRPC); + *attrp = fxdr_unsigned(int, *tl); + if (*attrp) { + error = nfs_loadattrcache(vp, &info->md, &info->dpos, + NULL, lflags); + if (error) { + *attrp = 0; + m_freem(info->mrep); + info->mrep = NULL; + return (error); + } + } + return (0); +} + +/* + * Caller is expected to abort if a non-zero error is returned. + */ +int +nfsm_wcc_data(nfsm_info_t info, struct vnode *vp, int *attrp) +{ + u_int32_t *tl; + int error; + int ttattrf; + int ttretf = 0; + + tl = nfsm_dissect(info, NFSX_UNSIGNED); + if (tl == NULL) + return (EBADRPC); + if (*tl == nfs_true) { + tl = nfsm_dissect(info, 6 * NFSX_UNSIGNED); + if (tl == NULL) + return (EBADRPC); + if (*attrp) { + ttretf = (VTONFS(vp)->n_mtime == + fxdr_unsigned(u_int32_t, *(tl + 2))); + if (ttretf == 0) + VTONFS(vp)->n_flag |= NRMODIFIED; + } + error = nfsm_postop_attr(info, vp, &ttattrf, + NFS_LATTR_NOSHRINK|NFS_LATTR_NOMTIMECHECK); + if (error) + return(error); + } else { + error = nfsm_postop_attr(info, vp, &ttattrf, + NFS_LATTR_NOSHRINK); + if (error) + return(error); + } + if (*attrp) + *attrp = ttretf; + else + *attrp = ttattrf; + return(0); +} + +/* + * This function updates the attribute cache based on data returned in the + * NFS reply for NFS RPCs that modify the target file. If the RPC succeeds + * a 'before' and 'after' mtime is returned that allows us to determine if + * the new mtime attribute represents our modification or someone else's + * modification. + * + * The flag argument returns non-0 if the original times matched, zero if + * they did not match. NRMODIFIED is automatically set if the before time + * does not match the original n_mtime, and n_mtime is automatically updated + * to the new after time (by nfsm_postop_attr()). + * + * If full is true, set all fields, otherwise just set mode and time fields + */ +void +nfsm_v3attrbuild(nfsm_info_t info, struct vattr *vap, int full) +{ + u_int32_t *tl; + + if (vap->va_mode != (mode_t)VNOVAL) { + tl = nfsm_build(info, 2 * NFSX_UNSIGNED); + *tl++ = nfs_true; + *tl = txdr_unsigned(vap->va_mode); + } else { + tl = nfsm_build(info, NFSX_UNSIGNED); + *tl = nfs_false; + } + if (full && vap->va_uid != (uid_t)VNOVAL) { + tl = nfsm_build(info, 2 * NFSX_UNSIGNED); + *tl++ = nfs_true; + *tl = txdr_unsigned(vap->va_uid); + } else { + tl = nfsm_build(info, NFSX_UNSIGNED); + *tl = nfs_false; + } + if (full && vap->va_gid != (gid_t)VNOVAL) { + tl = nfsm_build(info, 2 * NFSX_UNSIGNED); + *tl++ = nfs_true; + *tl = txdr_unsigned(vap->va_gid); + } else { + tl = nfsm_build(info, NFSX_UNSIGNED); + *tl = nfs_false; + } + if (full && vap->va_size != VNOVAL) { + tl = nfsm_build(info, 3 * NFSX_UNSIGNED); + *tl++ = nfs_true; + txdr_hyper(vap->va_size, tl); + } else { + tl = nfsm_build(info, NFSX_UNSIGNED); + *tl = nfs_false; + } + if (vap->va_atime.tv_sec != VNOVAL) { + if (vap->va_atime.tv_sec != time_second) { + tl = nfsm_build(info, 3 * NFSX_UNSIGNED); + *tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); + txdr_nfsv3time(&vap->va_atime, tl); + } else { + tl = nfsm_build(info, NFSX_UNSIGNED); + *tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); + } + } else { + tl = nfsm_build(info, NFSX_UNSIGNED); + *tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE); + } + if (vap->va_mtime.tv_sec != VNOVAL) { + if (vap->va_mtime.tv_sec != time_second) { + tl = nfsm_build(info, 3 * NFSX_UNSIGNED); + *tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); + txdr_nfsv3time(&vap->va_mtime, tl); + } else { + tl = nfsm_build(info, NFSX_UNSIGNED); + *tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); + } + } else { + tl = nfsm_build(info, NFSX_UNSIGNED); + *tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE); + } +} + +/* + * Caller is expected to abort with EBADRPC if a negative length is returned. + */ +int +nfsm_strsiz(nfsm_info_t info, int maxlen) +{ + u_int32_t *tl; + int len; + + tl = nfsm_dissect(info, NFSX_UNSIGNED); + if (tl == NULL) + return(-1); + len = fxdr_unsigned(int32_t, *tl); + if (len < 0 || len > maxlen) + return(-1); + return (len); +} + +/* + * Caller is expected to abort if a negative length is returned, but also + * call nfsm_reply(0) if -2 is returned. + * + * This function sets *errorp. Caller should not modify the error code. + */ +int +nfsm_srvstrsiz(nfsm_info_t info, int maxlen, int *errorp) +{ + u_int32_t *tl; + int len; + + tl = nfsm_dissect(info, NFSX_UNSIGNED); + if (tl == NULL) { + *errorp = EBADRPC; + return(-1); + } + len = fxdr_unsigned(int32_t,*tl); + if (len > maxlen || len <= 0) { + *errorp = EBADRPC; + return(-2); + } + return(len); +} + +/* + * Caller is expected to abort if a negative length is returned, but also + * call nfsm_reply(0) if -2 is returned. + * + * This function sets *errorp. Caller should not modify the error code. + */ +int +nfsm_srvnamesiz(nfsm_info_t info, int *errorp) +{ + u_int32_t *tl; + int len; + + tl = nfsm_dissect(info, NFSX_UNSIGNED); + if (tl == NULL) { + *errorp = EBADRPC; + return(-1); + } + + /* + * In this case if *errorp is not EBADRPC and we are NFSv3, + * nfsm_reply() will not return a negative number. But all + * call cases assume len is valid so we really do want + * to return -1. + */ + len = fxdr_unsigned(int32_t,*tl); + if (len > NFS_MAXNAMLEN) + *errorp = NFSERR_NAMETOL; + if (len <= 0) + *errorp = EBADRPC; + if (*errorp) + return(-2); + return (len); +} + +/* + * Caller is expected to abort if a non-zero error is returned. + */ +int +nfsm_mtouio(nfsm_info_t info, struct uio *uiop, int len) +{ + int error; + + if (len > 0 && + (error = nfsm_mbuftouio(&info->md, uiop, len, &info->dpos)) != 0) { + m_freem(info->mrep); + info->mrep = NULL; + return(error); + } + return(0); +} + +/* + * Caller is expected to abort if a non-zero error is returned. + */ +int +nfsm_uiotom(nfsm_info_t info, struct uio *uiop, int len) +{ + int error; + + if ((error = nfsm_uiotombuf(uiop, &info->mb, len, &info->bpos)) != 0) { + m_freem(info->mreq); + info->mreq = NULL; + return (error); + } + return(0); +} + +/* + * Caller is expected to abort if a negative value is returned. This + * function sets *errorp. Caller should not modify the error code. + */ +int +nfsm_request(nfsm_info_t info, struct vnode *vp, int procnum, + thread_t td, struct ucred *cred, int *errorp) +{ + *errorp = nfs_request(vp, info->mreq, procnum, td, cred, + &info->mrep, &info->md, &info->dpos); + if (*errorp) { + if ((*errorp & NFSERR_RETERR) == 0) + return(-1); + *errorp &= ~NFSERR_RETERR; + } + return(0); +} + +/* + * Caller is expected to abort if a non-zero error is returned. + */ +int +nfsm_strtom(nfsm_info_t info, const void *data, int len, int maxlen) +{ + u_int32_t *tl; + int error; + int n; + + if (len > maxlen) { + m_freem(info->mreq); + info->mreq = NULL; + return(ENAMETOOLONG); + } + n = nfsm_rndup(len) + NFSX_UNSIGNED; + if (n <= M_TRAILINGSPACE(info->mb)) { + tl = nfsm_build(info, n); + *tl++ = txdr_unsigned(len); + *(tl + ((n >> 2) - 2)) = 0; + bcopy(data, tl, len); + error = 0; + } else { + error = nfsm_strtmbuf(&info->mb, &info->bpos, data, len); + if (error) { + m_freem(info->mreq); + info->mreq = NULL; + } + } + return (error); +} + +/* + * Caller is expected to abort if a negative value is returned. This + * function sets *errorp. Caller should not modify the error code. + */ +int +nfsm_reply(nfsm_info_t info, + struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, + int siz, int *errorp) +{ + nfsd->nd_repstat = *errorp; + if (*errorp && !(nfsd->nd_flag & ND_NFSV3)) + siz = 0; + nfs_rephead(siz, nfsd, slp, *errorp, &info->mreq, + &info->mb, &info->bpos); + if (info->mrep != NULL) { + m_freem(info->mrep); + info->mrep = NULL; + } + if (*errorp && (!(nfsd->nd_flag & ND_NFSV3) || *errorp == EBADRPC)) { + *errorp = 0; + return(-1); + } + return(0); +} + +void +nfsm_writereply(nfsm_info_t info, + struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, + int error, int siz) +{ + nfsd->nd_repstat = error; + if (error && !(info->v3)) + siz = 0; + nfs_rephead(siz, nfsd, slp, error, &info->mreq, &info->mb, &info->bpos); +} + +/* + * Caller is expected to abort if a non-zero error is returned. + */ +int +nfsm_adv(nfsm_info_t info, int len) +{ + int error; + int n; + + n = mtod(info->md, caddr_t) + info->md->m_len - info->dpos; + if (n >= len) { + info->dpos += len; + error = 0; + } else if ((error = nfs_adv(&info->md, &info->dpos, len, n)) != 0) { + m_freem(info->mrep); + info->mrep = NULL; + } + return (error); +} + +/* + * Caller is expected to abort if a negative length is returned, but also + * call nfsm_reply(0) if -2 is returned. + * + * This function sets *errorp. Caller should not modify the error code. + */ +int +nfsm_srvmtofh(nfsm_info_t info, struct nfsrv_descript *nfsd, + fhandle_t *fhp, int *errorp) +{ + u_int32_t *tl; + int fhlen; + + if (nfsd->nd_flag & ND_NFSV3) { + tl = nfsm_dissect(info, NFSX_UNSIGNED); + if (tl == NULL) { + *errorp = EBADRPC; + return(-1); + } + fhlen = fxdr_unsigned(int, *tl); + if (fhlen != 0 && fhlen != NFSX_V3FH) { + *errorp = EBADRPC; + return(-2); + } + } else { + fhlen = NFSX_V2FH; + } + if (fhlen != 0) { + tl = nfsm_dissect(info, fhlen); + if (tl == NULL) { + *errorp = EBADRPC; + return(-1); + } + bcopy(tl, fhp, fhlen); + } else { + bzero(fhp, NFSX_V3FH); + } + return(0); +} + +void * +_nfsm_clget(nfsm_info_t info, struct mbuf *mp1, struct mbuf *mp2, + char *bp, char *be) +{ + u_int32_t *tl; + + if (bp >= be) { + if (mp1 == info->mb) + mp1->m_len += bp - info->bpos; + mp1 = m_getcl(MB_WAIT, MT_DATA, 0); + mp1->m_len = MCLBYTES; + mp2->m_next = mp1; + mp2 = mp1; + bp = mtod(mp1, caddr_t); + be = bp + mp1->m_len; + } + tl = (u_int32_t *)bp; + return (tl); +} + +int +nfsm_srvsattr(nfsm_info_t info, struct vattr *vap) +{ + u_int32_t *tl; + int error = 0; + + NULLOUT(tl = nfsm_dissect(info, NFSX_UNSIGNED)); + if (*tl == nfs_true) { + NULLOUT(tl = nfsm_dissect(info, NFSX_UNSIGNED)); + vap->va_mode = nfstov_mode(*tl); + } + NULLOUT(tl = nfsm_dissect(info, NFSX_UNSIGNED)); + if (*tl == nfs_true) { + NULLOUT(tl = nfsm_dissect(info, NFSX_UNSIGNED)); + vap->va_uid = fxdr_unsigned(uid_t, *tl); + } + NULLOUT(tl = nfsm_dissect(info, NFSX_UNSIGNED)); + if (*tl == nfs_true) { + NULLOUT(tl = nfsm_dissect(info, NFSX_UNSIGNED)); + vap->va_gid = fxdr_unsigned(gid_t, *tl); + } + NULLOUT(tl = nfsm_dissect(info, NFSX_UNSIGNED)); + if (*tl == nfs_true) { + NULLOUT(tl = nfsm_dissect(info, 2 * NFSX_UNSIGNED)); + vap->va_size = fxdr_hyper(tl); + } + NULLOUT(tl = nfsm_dissect(info, NFSX_UNSIGNED)); + switch (fxdr_unsigned(int, *tl)) { + case NFSV3SATTRTIME_TOCLIENT: + NULLOUT(tl = nfsm_dissect(info, 2 * NFSX_UNSIGNED)); + fxdr_nfsv3time(tl, &vap->va_atime); + break; + case NFSV3SATTRTIME_TOSERVER: + getnanotime(&vap->va_atime); + break; + }; + NULLOUT(tl = nfsm_dissect(info, NFSX_UNSIGNED)); + switch (fxdr_unsigned(int, *tl)) { + case NFSV3SATTRTIME_TOCLIENT: + NULLOUT(tl = nfsm_dissect(info, 2 * NFSX_UNSIGNED)); + fxdr_nfsv3time(tl, &vap->va_mtime); + break; + case NFSV3SATTRTIME_TOSERVER: + getnanotime(&vap->va_mtime); + break; + } +nfsmout: + return (error); } /* @@ -469,8 +1142,8 @@ nfsm_disct(struct mbuf **mdp, caddr_t *dposp, int siz, int left, caddr_t *cp2) xfer = (siz2 > mp2->m_len) ? mp2->m_len : siz2; if (xfer > 0) { bcopy(mtod(mp2, caddr_t), p, xfer); - NFSMADV(mp2, xfer); mp2->m_len -= xfer; + mp2->m_data += xfer; p += xfer; siz2 -= xfer; } @@ -633,22 +1306,20 @@ nfsm_adj(struct mbuf *mp, int len, int nul) * doesn't get too big... */ void -nfsm_srvwcc(struct nfsrv_descript *nfsd, int before_ret, - struct vattr *before_vap, int after_ret, struct vattr *after_vap, - struct mbuf **mbp, char **bposp) +nfsm_srvwcc_data(nfsm_info_t info, struct nfsrv_descript *nfsd, + int before_ret, struct vattr *before_vap, + int after_ret, struct vattr *after_vap) { - struct mbuf *mb = *mbp, *mb2; - char *bpos = *bposp; u_int32_t *tl; /* * before_ret is 0 if before_vap is valid, non-zero if it isn't. */ if (before_ret) { - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); + tl = nfsm_build(info, NFSX_UNSIGNED); *tl = nfs_false; } else { - nfsm_build(tl, u_int32_t *, 7 * NFSX_UNSIGNED); + tl = nfsm_build(info, 7 * NFSX_UNSIGNED); *tl++ = nfs_true; txdr_hyper(before_vap->va_size, tl); tl += 2; @@ -656,31 +1327,25 @@ nfsm_srvwcc(struct nfsrv_descript *nfsd, int before_ret, tl += 2; txdr_nfsv3time(&(before_vap->va_ctime), tl); } - *bposp = bpos; - *mbp = mb; - nfsm_srvpostopattr(nfsd, after_ret, after_vap, mbp, bposp); + nfsm_srvpostop_attr(info, nfsd, after_ret, after_vap); } void -nfsm_srvpostopattr(struct nfsrv_descript *nfsd, int after_ret, - struct vattr *after_vap, struct mbuf **mbp, char **bposp) +nfsm_srvpostop_attr(nfsm_info_t info, struct nfsrv_descript *nfsd, + int after_ret, struct vattr *after_vap) { - struct mbuf *mb = *mbp, *mb2; - char *bpos = *bposp; - u_int32_t *tl; struct nfs_fattr *fp; + u_int32_t *tl; if (after_ret) { - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); + tl = nfsm_build(info, NFSX_UNSIGNED); *tl = nfs_false; } else { - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED + NFSX_V3FATTR); + tl = nfsm_build(info, NFSX_UNSIGNED + NFSX_V3FATTR); *tl++ = nfs_true; fp = (struct nfs_fattr *)tl; nfsm_srvfattr(nfsd, after_vap, fp); } - *mbp = mb; - *bposp = bpos; } void diff --git a/sys/vfs/nfs/nfsm_subs.h b/sys/vfs/nfs/nfsm_subs.h index bc78b4ff5f..c01e4f9bc6 100644 --- a/sys/vfs/nfs/nfsm_subs.h +++ b/sys/vfs/nfs/nfsm_subs.h @@ -45,6 +45,50 @@ struct ucred; struct vnode; +struct nfsm_info { + struct nfsrv_descript *nfsd; + struct nfssvc_sock *slp; + struct mbuf *mb; + struct mbuf *mb2; + struct mbuf *md; + struct mbuf *mrep; + struct mbuf *mreq; + caddr_t bpos; + caddr_t dpos; + int32_t t2; + int v3; + int error; /* if non-zero goto nfsmout */ +}; + +typedef struct nfsm_info *nfsm_info_t; + +#define NULLOUT(nfsmexp) \ + do { if ((nfsmexp) == NULL) { \ + error = EBADRPC; goto nfsmout; } \ + } while(0) + +#define NEGATIVEOUT(nfsmexp) \ + do { if ((nfsmexp) < 0) { \ + error = EBADRPC; goto nfsmout; } \ + } while(0) + +#define NEGKEEPOUT(nfsmexp) \ + do { if ((nfsmexp) < 0) { \ + goto nfsmout; } \ + } while(0) + +#define NEGREPLYOUT(nfsmexp) \ + do { \ + int rv = (nfsmexp); \ + if (rv < 0) { \ + if (rv == -2) \ + nfsm_reply(&info, nfsd, slp, 0, &error); \ + goto nfsmout; \ + } \ + } while(0) + +#define ERROROUT(nfsmexp) if ((error = (nfsmexp)) != 0) goto nfsmout + /* * These macros do strange and peculiar things to mbuf chains for * the assistance of the nfs code. To attempt to use them for any @@ -54,518 +98,66 @@ struct vnode; /* * First define what the actual subs. return */ -struct mbuf *nfsm_reqh (struct vnode *vp, u_long procid, int hsiz, - caddr_t *bposp); +void nfsm_reqhead(nfsm_info_t info, struct vnode *vp, + u_long procid, int hsiz); struct mbuf *nfsm_rpchead (struct ucred *cr, int nmflag, int procid, - int auth_type, int auth_len, char *auth_str, - int verf_len, char *verf_str, - struct mbuf *mrest, int mrest_len, - struct mbuf **mbp, u_int32_t *xidp); - -#define M_HASCL(m) ((m)->m_flags & M_EXT) -#define NFSMINOFF(m) \ - do { \ - if (M_HASCL(m)) \ - (m)->m_data = (m)->m_ext.ext_buf; \ - else if ((m)->m_flags & M_PKTHDR) \ - (m)->m_data = (m)->m_pktdat; \ - else \ - (m)->m_data = (m)->m_dat; \ - } while (0) -#define NFSMADV(m, s) \ - do { \ - (m)->m_data += (s); \ - } while (0) -#define NFSMSIZ(m) ((M_HASCL(m))?MCLBYTES: \ - (((m)->m_flags & M_PKTHDR)?MHLEN:MLEN)) - -/* - * Now for the macros that do the simple stuff and call the functions - * for the hard stuff. - * These macros use several vars. declared in nfsm_reqhead and these - * vars. must not be used elsewhere unless you are careful not to corrupt - * them. The vars. starting with pN and tN (N=1,2,3,..) are temporaries - * that may be used so long as the value is not expected to retained - * after a macro. - * I know, this is kind of dorkey, but it makes the actual op functions - * fairly clean and deals with the mess caused by the xdr discriminating - * unions. - */ - -#define nfsm_build(a,c,s) \ - do { \ - if ((s) > M_TRAILINGSPACE(mb)) { \ - MGET(mb2, MB_WAIT, MT_DATA); \ - if ((s) > MLEN) \ - panic("build > MLEN"); \ - mb->m_next = mb2; \ - mb = mb2; \ - mb->m_len = 0; \ - bpos = mtod(mb, caddr_t); \ - } \ - (a) = (c)(bpos); \ - mb->m_len += (s); \ - bpos += (s); \ - } while (0) - -#define nfsm_dissect(a, c, s) \ - do { \ - t1 = mtod(md, caddr_t)+md->m_len-dpos; \ - if (t1 >= (s)) { \ - (a) = (c)(dpos); \ - dpos += (s); \ - } else if ((t1 = nfsm_disct(&md, &dpos, (s), t1, &cp2)) != 0){ \ - error = t1; \ - m_freem(mrep); \ - goto nfsmout; \ - } else { \ - (a) = (c)cp2; \ - } \ - } while (0) - -#define nfsm_fhtom(v, v3) \ - do { \ - if (v3) { \ - t2 = nfsm_rndup(VTONFS(v)->n_fhsize) + NFSX_UNSIGNED; \ - if (t2 <= M_TRAILINGSPACE(mb)) { \ - nfsm_build(tl, u_int32_t *, t2); \ - *tl++ = txdr_unsigned(VTONFS(v)->n_fhsize); \ - *(tl + ((t2>>2) - 2)) = 0; \ - bcopy((caddr_t)VTONFS(v)->n_fhp,(caddr_t)tl, \ - VTONFS(v)->n_fhsize); \ - } else if ((t2 = nfsm_strtmbuf(&mb, &bpos, \ - (caddr_t)VTONFS(v)->n_fhp, \ - VTONFS(v)->n_fhsize)) != 0) { \ - error = t2; \ - m_freem(mreq); \ - goto nfsmout; \ - } \ - } else { \ - nfsm_build(cp, caddr_t, NFSX_V2FH); \ - bcopy((caddr_t)VTONFS(v)->n_fhp, cp, NFSX_V2FH); \ - } \ - } while (0) - -#define nfsm_srvfhtom(f, v3) \ - do { \ - if (v3) { \ - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED + NFSX_V3FH);\ - *tl++ = txdr_unsigned(NFSX_V3FH); \ - bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \ - } else { \ - nfsm_build(cp, caddr_t, NFSX_V2FH); \ - bcopy((caddr_t)(f), cp, NFSX_V2FH); \ - } \ - } while (0) - -#define nfsm_srvpostop_fh(f) \ - do { \ - nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED + NFSX_V3FH); \ - *tl++ = nfs_true; \ - *tl++ = txdr_unsigned(NFSX_V3FH); \ - bcopy((caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \ - } while (0) + int auth_type, int auth_len, char *auth_str, + int verf_len, char *verf_str, + struct mbuf *mrest, int mrest_len, + struct mbuf **mbp, u_int32_t *xidp); +void *nfsm_build(nfsm_info_t info, int bytes); +void *nfsm_dissect(nfsm_info_t info, int bytes); +int nfsm_fhtom(nfsm_info_t info, struct vnode *vp); +void nfsm_srvfhtom(nfsm_info_t info, fhandle_t *fhp); +void nfsm_srvpostop_fh(nfsm_info_t info, fhandle_t *fhp); +int nfsm_mtofh(nfsm_info_t info, struct vnode *dvp, + struct vnode **vpp, int *gotvpp); +int nfsm_getfh(nfsm_info_t info, nfsfh_t **fhpp); +int nfsm_loadattr(nfsm_info_t info, struct vnode *vp, struct vattr *vap); +int nfsm_postop_attr(nfsm_info_t info, struct vnode *vp, + int *attrp, int lflags); +int nfsm_wcc_data(nfsm_info_t info, struct vnode *vp, int *attrp); +void nfsm_v3attrbuild(nfsm_info_t info, struct vattr *vap, int full); +int nfsm_strsiz(nfsm_info_t info, int maxlen); +int nfsm_srvstrsiz(nfsm_info_t info, int maxlen, int *errorp); +int nfsm_srvnamesiz(nfsm_info_t info, int *errorp); +int nfsm_mtouio(nfsm_info_t info, struct uio *uiop, int len); +int nfsm_uiotom(nfsm_info_t info, struct uio *uiop, int len); +int nfsm_request(nfsm_info_t info, struct vnode *vp, int procnum, + thread_t td, struct ucred *cred, int *errorp); +int nfsm_strtom(nfsm_info_t info, const void *data, int len, int maxlen); +int nfsm_reply(nfsm_info_t info, struct nfsrv_descript *nfsd, + struct nfssvc_sock *slp, int siz, int *errorp); +void nfsm_writereply(nfsm_info_t info, struct nfsrv_descript *nfsd, + struct nfssvc_sock *slp, int error, int siz); +int nfsm_adv(nfsm_info_t info, int len); +int nfsm_srvmtofh(nfsm_info_t info, struct nfsrv_descript *nfsd, + fhandle_t *fhp, int *errorp); +void *_nfsm_clget(nfsm_info_t info, struct mbuf *mp1, struct mbuf *mp2, + char *bp, char *be); +int nfsm_srvsattr(nfsm_info_t info, struct vattr *vap); +int nfsm_mbuftouio(struct mbuf **mrep, struct uio *uiop, + int siz, caddr_t *dpos); +int nfsm_uiotombuf (struct uio *uiop, struct mbuf **mq, + int siz, caddr_t *bpos); +int nfsm_disct(struct mbuf **mdp, caddr_t *dposp, int siz, + int left, caddr_t *cp2); +int nfsm_strtmbuf (struct mbuf **, char **, const char *, long); +void nfsm_adj(struct mbuf *mp, int len, int nul); +void nfsm_srvwcc_data(nfsm_info_t info, struct nfsrv_descript *nfsd, + int before_ret, struct vattr *before_vap, + int after_ret, struct vattr *after_vap); +void nfsm_srvpostop_attr(nfsm_info_t info, struct nfsrv_descript *nfsd, + int after_ret, struct vattr *after_vap); +void nfsm_srvfattr(struct nfsrv_descript *nfsd, struct vattr *vap, + struct nfs_fattr *fp); + +#define nfsm_clget(info, mp1, mp2, bp, be) \ + ((bp >= be) ? _nfsm_clget(info, mp1, mp2, bp, be) : (void *)bp) + +#define nfsm_rndup(a) (((a) + 3) & (~0x3)) -#define nfsm_mtofh(d, v, v3, f) \ - do { \ - 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(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); \ - } while (0) - -#define nfsm_getfh(f, s, v3) \ - do { \ - if (v3) { \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - if (((s) = fxdr_unsigned(int, *tl)) <= 0 || \ - (s) > NFSX_V3FHMAX) { \ - m_freem(mrep); \ - error = EBADRPC; \ - goto nfsmout; \ - } \ - } else \ - (s) = NFSX_V2FH; \ - nfsm_dissect((f), nfsfh_t *, nfsm_rndup(s)); \ - } while (0) - -#define nfsm_loadattr(v, a) \ - do { \ - struct vnode *ttvp = (v); \ - if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, (a), 0)) != 0) { \ - error = t1; \ - m_freem(mrep); \ - goto nfsmout; \ - } \ - (v) = ttvp; \ - } while (0) - -#define nfsm_postop_attr(v, f, lflags) \ - do { \ - struct vnode *ttvp = (v); \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - if (((f) = fxdr_unsigned(int, *tl)) != 0) { \ - if ((t1 = nfs_loadattrcache(&ttvp, &md, &dpos, \ - NULL, lflags)) != 0) { \ - error = t1; \ - (f) = 0; \ - m_freem(mrep); \ - goto nfsmout; \ - } \ - (v) = ttvp; \ - } \ - } while (0) - -/* - * This function updates the attribute cache based on data returned in the - * NFS reply for NFS RPCs that modify the target file. If the RPC succeeds - * a 'before' and 'after' mtime is returned that allows us to determine if - * the new mtime attribute represents our modification or someone else's - * modification. - * - * The flag argument returns non-0 if the original times matched, zero if - * they did not match. NRMODIFIED is automatically set if the before time - * does not match the original n_mtime, and n_mtime is automatically updated - * to the new after time (by nfsm_postop_attr()). - */ -/* Used as (f) for nfsm_wcc_data() */ #define NFSV3_WCCRATTR 0 #define NFSV3_WCCCHK 1 -#define nfsm_wcc_data(v, f) \ - do { \ - 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); \ - if (f) { \ - ttretf = (VTONFS(v)->n_mtime == \ - fxdr_unsigned(u_int32_t, *(tl + 2))); \ - if (!ttretf) \ - VTONFS(v)->n_flag |= NRMODIFIED; \ - } \ - nfsm_postop_attr((v), ttattrf, NFS_LATTR_NOSHRINK|NFS_LATTR_NOMTIMECHECK); \ - } else { \ - nfsm_postop_attr((v), ttattrf, NFS_LATTR_NOSHRINK); \ - } \ - if (f) { \ - (f) = ttretf; \ - } else { \ - (f) = ttattrf; \ - } \ - } while (0) - -/* If full is true, set all fields, otherwise just set mode and time fields */ -#define nfsm_v3attrbuild(a, full) \ - do { \ - if ((a)->va_mode != (mode_t)VNOVAL) { \ - nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \ - *tl++ = nfs_true; \ - *tl = txdr_unsigned((a)->va_mode); \ - } else { \ - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ - *tl = nfs_false; \ - } \ - if ((full) && (a)->va_uid != (uid_t)VNOVAL) { \ - nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \ - *tl++ = nfs_true; \ - *tl = txdr_unsigned((a)->va_uid); \ - } else { \ - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ - *tl = nfs_false; \ - } \ - if ((full) && (a)->va_gid != (gid_t)VNOVAL) { \ - nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \ - *tl++ = nfs_true; \ - *tl = txdr_unsigned((a)->va_gid); \ - } else { \ - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ - *tl = nfs_false; \ - } \ - if ((full) && (a)->va_size != VNOVAL) { \ - nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED); \ - *tl++ = nfs_true; \ - txdr_hyper((a)->va_size, tl); \ - } else { \ - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ - *tl = nfs_false; \ - } \ - if ((a)->va_atime.tv_sec != VNOVAL) { \ - if ((a)->va_atime.tv_sec != time_second) { \ - nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED);\ - *tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT);\ - txdr_nfsv3time(&(a)->va_atime, tl); \ - } else { \ - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ - *tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); \ - } \ - } else { \ - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ - *tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE); \ - } \ - if ((a)->va_mtime.tv_sec != VNOVAL) { \ - if ((a)->va_mtime.tv_sec != time_second) { \ - nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED);\ - *tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT);\ - txdr_nfsv3time(&(a)->va_mtime, tl); \ - } else { \ - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ - *tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); \ - } \ - } else { \ - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ - *tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE); \ - } \ - } while (0) - - -#define nfsm_strsiz(s,m) \ - do { \ - nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \ - if (((s) = fxdr_unsigned(int32_t,*tl)) > (m)) { \ - m_freem(mrep); \ - error = EBADRPC; \ - goto nfsmout; \ - } \ - } while (0) - -#define nfsm_srvstrsiz(s,m) \ - do { \ - nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \ - if (((s) = fxdr_unsigned(int32_t,*tl)) > (m) || (s) <= 0) { \ - error = EBADRPC; \ - nfsm_reply(0); \ - } \ - } while (0) - -#define nfsm_srvnamesiz(s) \ - do { \ - 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); \ - } while (0) - -#define nfsm_mtouio(p,s) \ - do {\ - if ((s) > 0 && \ - (t1 = nfsm_mbuftouio(&md,(p),(s),&dpos)) != 0) { \ - error = t1; \ - m_freem(mrep); \ - goto nfsmout; \ - } \ - } while (0) - -#define nfsm_uiotom(p,s) \ - do { \ - if ((t1 = nfsm_uiotombuf((p),&mb,(s),&bpos)) != 0) { \ - error = t1; \ - m_freem(mreq); \ - goto nfsmout; \ - } \ - } while (0) - -#define nfsm_reqhead(v,a,s) \ - do { \ - mb = mreq = nfsm_reqh((v),(a),(s),&bpos); \ - } while (0) - -#define nfsm_rndup(a) (((a)+3)&(~0x3)) - -#define nfsm_request(v, t, td, c) \ - do { \ - if ((error = nfs_request((v), mreq, (t), (td), \ - (c), &mrep, &md, &dpos)) != 0) { \ - if (error & NFSERR_RETERR) \ - error &= ~NFSERR_RETERR; \ - else \ - goto nfsmout; \ - } \ - } while (0) - -#define nfsm_strtom(a,s,m) \ - do {\ - if ((s) > (m)) { \ - m_freem(mreq); \ - error = ENAMETOOLONG; \ - goto nfsmout; \ - } \ - t2 = nfsm_rndup(s)+NFSX_UNSIGNED; \ - if (t2 <= M_TRAILINGSPACE(mb)) { \ - nfsm_build(tl,u_int32_t *,t2); \ - *tl++ = txdr_unsigned(s); \ - *(tl+((t2>>2)-2)) = 0; \ - bcopy((const char *)(a), (caddr_t)tl, (s)); \ - } else if ((t2 = nfsm_strtmbuf(&mb, &bpos, (a), (s))) != 0) { \ - error = t2; \ - m_freem(mreq); \ - goto nfsmout; \ - } \ - } while (0) - -#define nfsm_srvdone \ - do { \ - nfsmout: \ - return (error); \ - } while (0) - -#define nfsm_reply(s) \ - do { \ - nfsd->nd_repstat = error; \ - if (error && !(nfsd->nd_flag & ND_NFSV3)) \ - nfs_rephead(0, nfsd, slp, error, mrq, &mb, &bpos); \ - else \ - nfs_rephead((s), nfsd, slp, error, mrq, &mb, &bpos); \ - if (mrep != NULL) { \ - m_freem(mrep); \ - mrep = NULL; \ - } \ - mreq = *mrq; \ - if (error && (!(nfsd->nd_flag & ND_NFSV3) || \ - error == EBADRPC)) { \ - error = 0; \ - goto nfsmout; \ - } \ - } while (0) - -#define nfsm_writereply(s, v3) \ - do { \ - nfsd->nd_repstat = error; \ - if (error && !(v3)) \ - nfs_rephead(0, nfsd, slp, error, &mreq, &mb, &bpos); \ - else \ - nfs_rephead((s), nfsd, slp, error, &mreq, &mb, &bpos); \ - } while (0) - -#define nfsm_adv(s) \ - do { \ - t1 = mtod(md, caddr_t)+md->m_len-dpos; \ - if (t1 >= (s)) { \ - dpos += (s); \ - } else if ((t1 = nfs_adv(&md, &dpos, (s), t1)) != 0) { \ - error = t1; \ - m_freem(mrep); \ - goto nfsmout; \ - } \ - } while (0) - -#define nfsm_srvmtofh(f) \ - do { \ - int fhlen; \ - if (nfsd->nd_flag & ND_NFSV3) { \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - fhlen = fxdr_unsigned(int, *tl); \ - if (fhlen != 0 && fhlen != NFSX_V3FH) { \ - error = EBADRPC; \ - nfsm_reply(0); \ - } \ - } else { \ - fhlen = NFSX_V2FH; \ - } \ - if (fhlen != 0) { \ - nfsm_dissect(tl, u_int32_t *, fhlen); \ - bcopy((caddr_t)tl, (caddr_t)(f), fhlen); \ - } else {\ - bzero((caddr_t)(f), NFSX_V3FH); \ - } \ - } while (0) - -#define nfsm_clget(mp1, mp2, mb, bp, be, tl) \ - do { \ - if (bp >= be) { \ - if (mp1 == mb) \ - mp1->m_len += bp-bpos; \ - mp1 = m_getcl(MB_WAIT, MT_DATA, 0); \ - mp1->m_len = MCLBYTES; \ - mp2->m_next = mp1; \ - mp2 = mp1; \ - bp = mtod(mp1, caddr_t); \ - be = bp+mp1->m_len; \ - } \ - tl = (u_int32_t *)bp; \ - } while (0) - -#define nfsm_srvfillattr(a, f) \ - do { \ - nfsm_srvfattr(nfsd, (a), (f)); \ - } while (0) - -#define nfsm_srvwcc_data(br, b, ar, a) \ - do { \ - nfsm_srvwcc(nfsd, (br), (b), (ar), (a), &mb, &bpos); \ - } while (0) - -#define nfsm_srvpostop_attr(r, a) \ - do { \ - nfsm_srvpostopattr(nfsd, (r), (a), &mb, &bpos); \ - } while (0) - -#define nfsm_srvsattr(a) \ - do { \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - if (*tl == nfs_true) { \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - (a)->va_mode = nfstov_mode(*tl); \ - } \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - if (*tl == nfs_true) { \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - (a)->va_uid = fxdr_unsigned(uid_t, *tl); \ - } \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - if (*tl == nfs_true) { \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - (a)->va_gid = fxdr_unsigned(gid_t, *tl); \ - } \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - if (*tl == nfs_true) { \ - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \ - (a)->va_size = fxdr_hyper(tl); \ - } \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - switch (fxdr_unsigned(int, *tl)) { \ - case NFSV3SATTRTIME_TOCLIENT: \ - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \ - fxdr_nfsv3time(tl, &(a)->va_atime); \ - break; \ - case NFSV3SATTRTIME_TOSERVER: \ - getnanotime(&(a)->va_atime); \ - break; \ - }; \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - switch (fxdr_unsigned(int, *tl)) { \ - case NFSV3SATTRTIME_TOCLIENT: \ - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \ - fxdr_nfsv3time(tl, &(a)->va_mtime); \ - break; \ - case NFSV3SATTRTIME_TOSERVER: \ - getnanotime(&(a)->va_mtime); \ - break; \ - } \ - } while (0) - #endif -- 2.41.0