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 **,
-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);
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);
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;
}
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);
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;
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);
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;
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
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;
}
* 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 ||
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;
}
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);
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;
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);
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);
/*
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;
}
}
if (dirp) {
- if (v3)
+ if (info.v3)
dirattr_ret = VOP_GETATTR(dirp, &dirattr);
vrele(dirp);
dirp = NULL;
*/
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;
}
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 */
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
#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) {
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;
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;
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)
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;
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
&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;
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;
}
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));
}
* 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) {
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) {
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;
}
}
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;
}
*tl = txdr_unsigned(cnt);
nfsmout:
+ *mrq = info.mreq;
if (vp)
vput(vp);
return(error);
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;
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)
*/
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;
}
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;
}
&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;
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;
}
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);
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.
*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);
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
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)
*/
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;
}
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;
}
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;
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)
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);
}
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);
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);
/*
*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");
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;
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;
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);
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
* 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);
}
}
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_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:
}
/* 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;
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);
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;
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);
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);
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
*/
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);
}
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);
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);
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) {
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);
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;
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
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.
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;
}
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)
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;
}
}
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;
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);
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;
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);
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;
}
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)
/* 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);
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);
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;
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';
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);
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);
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++);
}
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);
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;
nfsfh_t nfh;
fhandle_t *fhp;
struct nlookupdata nd;
+ struct nfsm_info info;
nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
nlookup_zero(&nd);
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;
}
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);
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;
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 */
}
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;
}
* Obtain lock on vnode for this section of the code
*/
- if (v3) {
+ if (info.v3) {
error = getret = VOP_GETATTR(vp, &at);
#if 0
/*
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;
}
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;
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;
}
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);
}
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 */
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;
* 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;
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
/* 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;
}
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);
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;
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);
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;
}
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;
}
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;
}
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;
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;
}
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 */
* 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;
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
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
}
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);
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;
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
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;
}
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);
error = 0;
}
nfsmout:
+ *mrq = info.mreq;
if (vp)
vput(vp);
return(error);
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;
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;
}
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);
sfp->sf_bavail = txdr_unsigned(sf->f_bavail);
}
nfsmout:
+ *mrq = info.mreq;
if (vp)
vput(vp);
return(error);
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;
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;
}
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
NFSV3FSINFO_SYMLINK | NFSV3FSINFO_HOMOGENEOUS |
NFSV3FSINFO_CANSETTIME);
nfsmout:
+ *mrq = info.mreq;
if (vp)
vput(vp);
return(error);
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;
}
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);
pc->pc_caseinsensitive = nfs_false;
pc->pc_casepreserving = nfs_true;
nfsmout:
+ *mrq = info.mreq;
if (vp)
vput(vp);
return(error);
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);
}
/*
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);
}
/*
{
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
* case, the lock is not taken to avoid races with
* other processes.
*/
+ info.mrep = NULL;
+
error = nfs_rcvlock(myrep);
if (error == EALREADY)
return (0);
/*
* 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) {
/*
/*
* 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);
* 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;
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);
}
/*
*/
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");
{
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.
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);
/*
* 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;
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 {
} 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);
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)
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);
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)) {
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);
*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 {
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;
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
}
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);
{
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) {
auth_type = *tl++;
len = fxdr_unsigned(int, *tl++);
if (len < 0 || len > RPCAUTH_MAXSIZ) {
- m_freem(mrep);
+ m_freem(info.mrep);
return (EBADRPC);
}
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++);
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:
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;
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");
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");
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");
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;
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);
* 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;
{
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);
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);
}
{
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;
/* 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));
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);
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) &
nmp->nm_maxfilesize = maxfsize;
nmp->nm_state |= NFSSTA_GOTFSINFO;
}
- m_freem(mrep);
+ m_freem(info.mrep);
+ info.mrep = NULL;
nfsmout:
return (error);
}
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;
}
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;
{
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.
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)
}
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);
}
{
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
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);
}
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;
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
*/
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;
}
* 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)) {
} 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) {
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.
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;
} 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) {
}
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) &&
}
#endif
*vpp = newvp;
- m_freem(mrep);
+ m_freem(info.mrep);
+ info.mrep = NULL;
nfsmout:
if (error) {
if (newvp != NULLVP) {
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);
}
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;
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 {
*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;
}
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)
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);
} 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" */
*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
* 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;
}
}
} 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;
{
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);
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;
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);
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)
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..
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;
*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;
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);
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
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)
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;
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);
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)
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;
* 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:
/*
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;
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)
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)
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)) ||
*/
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;
}
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
* 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));
}
/*
*/
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++;
* 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
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;
struct nchandle nch;
struct nchandle dnch;
struct nlcomponent nlc;
+ struct nfsm_info info;
+
+ info.mrep = NULL;
+ info.v3 = 1;
#ifndef nolint
dp = NULL;
*/
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);
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';
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++;
*/
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;
}
}
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) {
}
} 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)
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
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) {
} 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) {
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,
error = NFSERR_STALEWRITEVERF;
}
}
- m_freem(mrep);
+ m_freem(info.mrep);
+ info.mrep = NULL;
nfsmout:
return (error);
}
* 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);
}
/*
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)
*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);
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;
};
/*
* 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);
}
/*
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;
}
* 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;
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
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
/*
* 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