Add DEXITCODE plumbing to NFS.
Isilon has the concept of an in-memory exit-code ring that saves the last exit code of a function and allows for stack tracing. This is very helpful when debugging tough issues. This patch is essentially a no-op for BSD at this point, until we upstream the dexitcode logic itself. The patch adds DEXITCODE calls to every NFS function that returns an errno error code. A number of code paths were also reorganized to have single exit paths, to reduce code duplication. Submitted by: David Kwan <dkwan@isilon.com> Reviewed by: rmacklem Approved by: zml (mentor) MFC after: 2 weeks
This commit is contained in:
parent
4eb5923d1a
commit
a9285ae5c4
@ -59,7 +59,8 @@ nfsrv_dissectace(struct nfsrv_descript *nd, struct acl_entry *acep,
|
||||
mask = fxdr_unsigned(u_int32_t, *tl++);
|
||||
len = fxdr_unsigned(int, *tl);
|
||||
if (len < 0) {
|
||||
return (NFSERR_BADXDR);
|
||||
error = NFSERR_BADXDR;
|
||||
goto nfsmout;
|
||||
} else if (len == 0) {
|
||||
/* Netapp filers return a 0 length who for nil users */
|
||||
acep->ae_tag = ACL_UNDEFINED_TAG;
|
||||
@ -68,7 +69,8 @@ nfsrv_dissectace(struct nfsrv_descript *nd, struct acl_entry *acep,
|
||||
acep->ae_entry_type = ACL_ENTRY_TYPE_DENY;
|
||||
if (acesizep)
|
||||
*acesizep = 4 * NFSX_UNSIGNED;
|
||||
return (0);
|
||||
error = 0;
|
||||
goto nfsmout;
|
||||
}
|
||||
if (len > NFSV4_SMALLSTR)
|
||||
name = malloc(len + 1, M_NFSSTRING, M_WAITOK);
|
||||
@ -78,7 +80,7 @@ nfsrv_dissectace(struct nfsrv_descript *nd, struct acl_entry *acep,
|
||||
if (error) {
|
||||
if (len > NFSV4_SMALLSTR)
|
||||
free(name, M_NFSSTRING);
|
||||
return (error);
|
||||
goto nfsmout;
|
||||
}
|
||||
if (len == 6) {
|
||||
if (!NFSBCMP(name, "OWNER@", 6)) {
|
||||
@ -171,8 +173,9 @@ nfsrv_dissectace(struct nfsrv_descript *nd, struct acl_entry *acep,
|
||||
*aceerrp = aceerr;
|
||||
if (acesizep)
|
||||
*acesizep = NFSM_RNDUP(len) + (4 * NFSX_UNSIGNED);
|
||||
return (0);
|
||||
error = 0;
|
||||
nfsmout:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -184,6 +187,7 @@ nfsrv_acemasktoperm(u_int32_t acetype, u_int32_t mask, int owner,
|
||||
enum vtype type, acl_perm_t *permp)
|
||||
{
|
||||
acl_perm_t perm = 0x0;
|
||||
int error = 0;
|
||||
|
||||
if (mask & NFSV4ACE_READDATA) {
|
||||
mask &= ~NFSV4ACE_READDATA;
|
||||
@ -257,10 +261,15 @@ nfsrv_acemasktoperm(u_int32_t acetype, u_int32_t mask, int owner,
|
||||
mask &= ~NFSV4ACE_SYNCHRONIZE;
|
||||
perm |= ACL_SYNCHRONIZE;
|
||||
}
|
||||
if (mask != 0)
|
||||
return (NFSERR_ATTRNOTSUPP);
|
||||
if (mask != 0) {
|
||||
error = NFSERR_ATTRNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
*permp = perm;
|
||||
return (0);
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/* local functions */
|
||||
@ -445,19 +454,26 @@ nfsrv_setacl(vnode_t vp, NFSACL_T *aclp, struct ucred *cred,
|
||||
{
|
||||
int error;
|
||||
|
||||
if (nfsrv_useacl == 0 || nfs_supportsnfsv4acls(vp) == 0)
|
||||
return (NFSERR_ATTRNOTSUPP);
|
||||
if (nfsrv_useacl == 0 || nfs_supportsnfsv4acls(vp) == 0) {
|
||||
error = NFSERR_ATTRNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* With NFSv4 ACLs, chmod(2) may need to add additional entries.
|
||||
* Make sure it has enough room for that - splitting every entry
|
||||
* into two and appending "canonical six" entries at the end.
|
||||
* Cribbed out of kern/vfs_acl.c - Rick M.
|
||||
*/
|
||||
if (aclp->acl_cnt > (ACL_MAX_ENTRIES - 6) / 2)
|
||||
return (NFSERR_ATTRNOTSUPP);
|
||||
if (aclp->acl_cnt > (ACL_MAX_ENTRIES - 6) / 2) {
|
||||
error = NFSERR_ATTRNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
error = VOP_ACLCHECK(vp, ACL_TYPE_NFS4, aclp, cred, p);
|
||||
if (!error)
|
||||
error = VOP_SETACL(vp, ACL_TYPE_NFS4, aclp, cred, p);
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -166,7 +166,7 @@ newnfs_connect(struct nfsmount *nmp, struct nfssockreq *nrp,
|
||||
CLIENT *client;
|
||||
struct netconfig *nconf;
|
||||
struct socket *so;
|
||||
int one = 1, retries, error;
|
||||
int one = 1, retries, error = 0;
|
||||
struct thread *td = curthread;
|
||||
|
||||
/*
|
||||
@ -222,7 +222,7 @@ newnfs_connect(struct nfsmount *nmp, struct nfssockreq *nrp,
|
||||
nrp->nr_soproto, td->td_ucred, td);
|
||||
if (error) {
|
||||
td->td_ucred = origcred;
|
||||
return (error);
|
||||
goto out;
|
||||
}
|
||||
do {
|
||||
if (error != 0 && pktscale > 2)
|
||||
@ -253,7 +253,7 @@ newnfs_connect(struct nfsmount *nmp, struct nfssockreq *nrp,
|
||||
soclose(so);
|
||||
if (error) {
|
||||
td->td_ucred = origcred;
|
||||
return (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
client = clnt_reconnect_create(nconf, saddr, nrp->nr_prog,
|
||||
@ -307,7 +307,10 @@ newnfs_connect(struct nfsmount *nmp, struct nfssockreq *nrp,
|
||||
|
||||
/* Restore current thread's credentials. */
|
||||
td->td_ucred = origcred;
|
||||
return (0);
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -329,6 +329,7 @@ nfsvno_pathconf(struct vnode *vp, int flag, register_t *retf,
|
||||
};
|
||||
error = 0;
|
||||
}
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -427,6 +428,7 @@ nfssvc_nfscommon(struct thread *td, struct nfssvc_args *uap)
|
||||
int error;
|
||||
|
||||
error = nfssvc_call(td, uap, td->td_ucred);
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -439,9 +441,9 @@ nfssvc_call(struct thread *p, struct nfssvc_args *uap, struct ucred *cred)
|
||||
if (uap->flag & NFSSVC_IDNAME) {
|
||||
error = copyin(uap->argp, (caddr_t)&nid, sizeof (nid));
|
||||
if (error)
|
||||
return (error);
|
||||
goto out;
|
||||
error = nfssvc_idname(&nid);
|
||||
return (error);
|
||||
goto out;
|
||||
} else if (uap->flag & NFSSVC_GETSTATS) {
|
||||
error = copyout(&newnfsstats,
|
||||
CAST_USER_ADDR_T(uap->argp), sizeof (newnfsstats));
|
||||
@ -503,7 +505,7 @@ nfssvc_call(struct thread *p, struct nfssvc_args *uap, struct ucred *cred)
|
||||
sizeof(newnfsstats.cbrpccnt));
|
||||
}
|
||||
}
|
||||
return (error);
|
||||
goto out;
|
||||
} else if (uap->flag & NFSSVC_NFSUSERDPORT) {
|
||||
u_short sockport;
|
||||
|
||||
@ -515,6 +517,9 @@ nfssvc_call(struct thread *p, struct nfssvc_args *uap, struct ucred *cred)
|
||||
nfsrv_nfsuserddelport();
|
||||
error = 0;
|
||||
}
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -569,7 +574,7 @@ nfscommon_modevent(module_t mod, int type, void *data)
|
||||
switch (type) {
|
||||
case MOD_LOAD:
|
||||
if (loaded)
|
||||
return (0);
|
||||
goto out;
|
||||
newnfs_portinit();
|
||||
mtx_init(&nfs_nameid_mutex, "nfs_nameid_mutex", NULL, MTX_DEF);
|
||||
mtx_init(&nfs_sockl_mutex, "nfs_sockl_mutex", NULL, MTX_DEF);
|
||||
@ -606,6 +611,9 @@ nfscommon_modevent(module_t mod, int type, void *data)
|
||||
error = EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return error;
|
||||
}
|
||||
static moduledata_t nfscommon_mod = {
|
||||
|
@ -179,8 +179,10 @@ nfsm_mbufuio(struct nfsrv_descript *nd, struct uio *uiop, int siz)
|
||||
len = NFSMTOD(mp, caddr_t) + mbuf_len(mp) - mbufcp;
|
||||
rem = NFSM_RNDUP(siz) - siz;
|
||||
while (siz > 0) {
|
||||
if (uiop->uio_iovcnt <= 0 || uiop->uio_iov == NULL)
|
||||
return (EBADRPC);
|
||||
if (uiop->uio_iovcnt <= 0 || uiop->uio_iov == NULL) {
|
||||
error = EBADRPC;
|
||||
goto out;
|
||||
}
|
||||
left = uiop->uio_iov->iov_len;
|
||||
uiocp = uiop->uio_iov->iov_base;
|
||||
if (left > siz)
|
||||
@ -189,8 +191,10 @@ nfsm_mbufuio(struct nfsrv_descript *nd, struct uio *uiop, int siz)
|
||||
while (left > 0) {
|
||||
while (len == 0) {
|
||||
mp = mbuf_next(mp);
|
||||
if (mp == NULL)
|
||||
return (EBADRPC);
|
||||
if (mp == NULL) {
|
||||
error = EBADRPC;
|
||||
goto out;
|
||||
}
|
||||
mbufcp = NFSMTOD(mp, caddr_t);
|
||||
len = mbuf_len(mp);
|
||||
}
|
||||
@ -231,6 +235,9 @@ nfsm_mbufuio(struct nfsrv_descript *nd, struct uio *uiop, int siz)
|
||||
else
|
||||
nd->nd_dpos += rem;
|
||||
}
|
||||
|
||||
out:
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
#endif /* !APPLE */
|
||||
@ -308,9 +315,10 @@ nfsm_dissct(struct nfsrv_descript *nd, int siz)
|
||||
APPLESTATIC int
|
||||
nfsm_advance(struct nfsrv_descript *nd, int offs, int left)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
if (offs == 0)
|
||||
return (0);
|
||||
goto out;
|
||||
/*
|
||||
* A negative offs should be considered a serious problem.
|
||||
*/
|
||||
@ -330,13 +338,18 @@ nfsm_advance(struct nfsrv_descript *nd, int offs, int left)
|
||||
while (offs > left) {
|
||||
offs -= left;
|
||||
nd->nd_md = mbuf_next(nd->nd_md);
|
||||
if (nd->nd_md == NULL)
|
||||
return (EBADRPC);
|
||||
if (nd->nd_md == NULL) {
|
||||
error = EBADRPC;
|
||||
goto out;
|
||||
}
|
||||
left = mbuf_len(nd->nd_md);
|
||||
nd->nd_dpos = NFSMTOD(nd->nd_md, caddr_t);
|
||||
}
|
||||
nd->nd_dpos += offs;
|
||||
return (0);
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -620,8 +633,10 @@ nfsm_getfh(struct nfsrv_descript *nd, struct nfsfh **nfhpp)
|
||||
if (nd->nd_flag & (ND_NFSV3 | ND_NFSV4)) {
|
||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||
if ((len = fxdr_unsigned(int, *tl)) <= 0 ||
|
||||
len > NFSX_FHMAX)
|
||||
return (EBADRPC);
|
||||
len > NFSX_FHMAX) {
|
||||
error = EBADRPC;
|
||||
goto nfsmout;
|
||||
}
|
||||
} else
|
||||
len = NFSX_V2FH;
|
||||
MALLOC(nfhp, struct nfsfh *, sizeof (struct nfsfh) + len,
|
||||
@ -629,11 +644,12 @@ nfsm_getfh(struct nfsrv_descript *nd, struct nfsfh **nfhpp)
|
||||
error = nfsrv_mtostr(nd, nfhp->nfh_fh, len);
|
||||
if (error) {
|
||||
FREE((caddr_t)nfhp, M_NFSFH);
|
||||
return (error);
|
||||
goto nfsmout;
|
||||
}
|
||||
nfhp->nfh_len = len;
|
||||
*nfhpp = nfhp;
|
||||
nfsmout:
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -670,7 +686,7 @@ nfsrv_dissectacl(struct nfsrv_descript *nd, NFSACL_T *aclp, int *aclerrp,
|
||||
else
|
||||
error = nfsrv_skipace(nd, &acesize);
|
||||
if (error)
|
||||
return (error);
|
||||
goto nfsmout;
|
||||
aclsize += acesize;
|
||||
}
|
||||
if (aclp && !aceerr)
|
||||
@ -680,6 +696,7 @@ nfsrv_dissectacl(struct nfsrv_descript *nd, NFSACL_T *aclp, int *aclerrp,
|
||||
if (aclsizep)
|
||||
*aclsizep = aclsize;
|
||||
nfsmout:
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -697,6 +714,7 @@ nfsrv_skipace(struct nfsrv_descript *nd, int *acesizep)
|
||||
error = nfsm_advance(nd, NFSM_RNDUP(len), -1);
|
||||
nfsmout:
|
||||
*acesizep = NFSM_RNDUP(len) + (4 * NFSX_UNSIGNED);
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -715,8 +733,10 @@ nfsrv_getattrbits(struct nfsrv_descript *nd, nfsattrbit_t *attrbitp, int *cntp,
|
||||
|
||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||
cnt = fxdr_unsigned(int, *tl);
|
||||
if (cnt < 0)
|
||||
return (NFSERR_BADXDR);
|
||||
if (cnt < 0) {
|
||||
error = NFSERR_BADXDR;
|
||||
goto nfsmout;
|
||||
}
|
||||
if (cnt > NFSATTRBIT_MAXWORDS) {
|
||||
outcnt = NFSATTRBIT_MAXWORDS;
|
||||
if (retnotsupp)
|
||||
@ -735,6 +755,7 @@ nfsrv_getattrbits(struct nfsrv_descript *nd, nfsattrbit_t *attrbitp, int *cntp,
|
||||
if (cntp)
|
||||
*cntp = NFSX_UNSIGNED + (cnt * NFSX_UNSIGNED);
|
||||
nfsmout:
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -756,7 +777,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
u_int32_t *leasep, u_int32_t *rderrp, NFSPROC_T *p, struct ucred *cred)
|
||||
{
|
||||
u_int32_t *tl;
|
||||
int i = 0, j, k, l, m, bitpos, attrsum = 0;
|
||||
int i = 0, j, k, l = 0, m, bitpos, attrsum = 0;
|
||||
int error, tfhsize, aceerr, attrsize, cnt, retnotsup;
|
||||
u_char *cp, *cp2, namestr[NFSV4_SMALLSTR + 1];
|
||||
nfsattrbit_t attrbits, retattrbits, checkattrbits;
|
||||
@ -783,7 +804,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
error = nfsrv_getattrbits(nd, &attrbits, NULL, NULL);
|
||||
}
|
||||
if (error)
|
||||
return (error);
|
||||
goto nfsmout;
|
||||
|
||||
if (compare) {
|
||||
*retcmpp = retnotsup;
|
||||
@ -854,7 +875,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
error = nfsrv_getattrbits(nd, &nap->na_suppattr,
|
||||
&cnt, &retnotsup);
|
||||
if (error)
|
||||
return (error);
|
||||
goto nfsmout;
|
||||
if (compare && !(*retcmpp)) {
|
||||
NFSSETSUPP_ATTRBIT(&checkattrbits);
|
||||
if (!NFSEQUAL_ATTRBIT(&retattrbits, &checkattrbits)
|
||||
@ -1015,7 +1036,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
&cnt, p);
|
||||
if (error) {
|
||||
acl_free(naclp);
|
||||
return (error);
|
||||
goto nfsmout;
|
||||
}
|
||||
if (aceerr || nfsrv_compareacl(aclp, naclp))
|
||||
*retcmpp = NFSERR_NOTSAME;
|
||||
@ -1034,7 +1055,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
error = nfsrv_dissectacl(nd, NULL, &aceerr,
|
||||
&cnt, p);
|
||||
if (error)
|
||||
return (error);
|
||||
goto nfsmout;
|
||||
}
|
||||
attrsum += cnt;
|
||||
break;
|
||||
@ -1123,7 +1144,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
case NFSATTRBIT_FILEHANDLE:
|
||||
error = nfsm_getfh(nd, &tnfhp);
|
||||
if (error)
|
||||
return (error);
|
||||
goto nfsmout;
|
||||
tfhsize = tnfhp->nfh_len;
|
||||
if (compare) {
|
||||
if (!(*retcmpp) &&
|
||||
@ -1189,7 +1210,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
case NFSATTRBIT_FSLOCATIONS:
|
||||
error = nfsrv_getrefstr(nd, &cp, &cp2, &l, &m);
|
||||
if (error)
|
||||
return (error);
|
||||
goto nfsmout;
|
||||
attrsum += l;
|
||||
if (compare && !(*retcmpp)) {
|
||||
refp = nfsv4root_getreferral(vp, NULL, 0);
|
||||
@ -1365,8 +1386,10 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
case NFSATTRBIT_OWNER:
|
||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||
j = fxdr_unsigned(int, *tl);
|
||||
if (j < 0)
|
||||
return (NFSERR_BADXDR);
|
||||
if (j < 0) {
|
||||
error = NFSERR_BADXDR;
|
||||
goto nfsmout;
|
||||
}
|
||||
attrsum += (NFSX_UNSIGNED + NFSM_RNDUP(j));
|
||||
if (j > NFSV4_SMALLSTR)
|
||||
cp = malloc(j + 1, M_NFSSTRING, M_WAITOK);
|
||||
@ -1376,7 +1399,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
if (error) {
|
||||
if (j > NFSV4_SMALLSTR)
|
||||
free(cp, M_NFSSTRING);
|
||||
return (error);
|
||||
goto nfsmout;
|
||||
}
|
||||
if (compare) {
|
||||
if (!(*retcmpp)) {
|
||||
@ -1396,8 +1419,10 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
case NFSATTRBIT_OWNERGROUP:
|
||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||
j = fxdr_unsigned(int, *tl);
|
||||
if (j < 0)
|
||||
return (NFSERR_BADXDR);
|
||||
if (j < 0) {
|
||||
error = NFSERR_BADXDR;
|
||||
goto nfsmout;
|
||||
}
|
||||
attrsum += (NFSX_UNSIGNED + NFSM_RNDUP(j));
|
||||
if (j > NFSV4_SMALLSTR)
|
||||
cp = malloc(j + 1, M_NFSSTRING, M_WAITOK);
|
||||
@ -1407,7 +1432,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
if (error) {
|
||||
if (j > NFSV4_SMALLSTR)
|
||||
free(cp, M_NFSSTRING);
|
||||
return (error);
|
||||
goto nfsmout;
|
||||
}
|
||||
if (compare) {
|
||||
if (!(*retcmpp)) {
|
||||
@ -1713,6 +1738,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
error = nfsm_advance(nd, attrsize - attrsum, -1);
|
||||
}
|
||||
nfsmout:
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -1909,8 +1935,10 @@ nfsrv_mtostr(struct nfsrv_descript *nd, char *str, int siz)
|
||||
siz -= xfer;
|
||||
if (siz > 0) {
|
||||
mp = mbuf_next(mp);
|
||||
if (mp == NULL)
|
||||
return (EBADRPC);
|
||||
if (mp == NULL) {
|
||||
error = EBADRPC;
|
||||
goto out;
|
||||
}
|
||||
cp = NFSMTOD(mp, caddr_t);
|
||||
len = mbuf_len(mp);
|
||||
} else {
|
||||
@ -1927,6 +1955,9 @@ nfsrv_mtostr(struct nfsrv_descript *nd, char *str, int siz)
|
||||
else
|
||||
nd->nd_dpos += rem;
|
||||
}
|
||||
|
||||
out:
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -2576,9 +2607,12 @@ nfsv4_strtouid(u_char *str, int len, uid_t *uidp, NFSPROC_T *p)
|
||||
u_char *cp;
|
||||
struct nfsusrgrp *usrp;
|
||||
int cnt, ret;
|
||||
int error = 0;
|
||||
|
||||
if (len == 0)
|
||||
return (NFSERR_BADOWNER);
|
||||
if (len == 0) {
|
||||
error = NFSERR_BADOWNER;
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* Look for an '@'.
|
||||
*/
|
||||
@ -2609,7 +2643,8 @@ nfsv4_strtouid(u_char *str, int len, uid_t *uidp, NFSPROC_T *p)
|
||||
if (len == 6 && !NFSBCMP(str, "nobody", 6)) {
|
||||
*uidp = nfsrv_defaultuid;
|
||||
NFSUNLOCKNAMEID();
|
||||
return (0);
|
||||
error = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
LIST_FOREACH(usrp, NFSUSERNAMEHASH(str, len), lug_namehash) {
|
||||
@ -2621,7 +2656,8 @@ nfsv4_strtouid(u_char *str, int len, uid_t *uidp, NFSPROC_T *p)
|
||||
TAILQ_REMOVE(&nfsuserlruhead, usrp, lug_lru);
|
||||
TAILQ_INSERT_TAIL(&nfsuserlruhead, usrp, lug_lru);
|
||||
NFSUNLOCKNAMEID();
|
||||
return (0);
|
||||
error = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
NFSUNLOCKNAMEID();
|
||||
@ -2630,7 +2666,11 @@ nfsv4_strtouid(u_char *str, int len, uid_t *uidp, NFSPROC_T *p)
|
||||
str, p);
|
||||
if (ret == 0 && cnt < 2)
|
||||
goto tryagain;
|
||||
return (NFSERR_BADOWNER);
|
||||
error = NFSERR_BADOWNER;
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2756,9 +2796,12 @@ nfsv4_strtogid(u_char *str, int len, gid_t *gidp, NFSPROC_T *p)
|
||||
u_char *cp;
|
||||
struct nfsusrgrp *usrp;
|
||||
int cnt, ret;
|
||||
int error = 0;
|
||||
|
||||
if (len == 0)
|
||||
return (NFSERR_BADOWNER);
|
||||
if (len == 0) {
|
||||
error = NFSERR_BADOWNER;
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* Look for an '@'.
|
||||
*/
|
||||
@ -2787,7 +2830,8 @@ nfsv4_strtogid(u_char *str, int len, gid_t *gidp, NFSPROC_T *p)
|
||||
if (len == 7 && !NFSBCMP(str, "nogroup", 7)) {
|
||||
*gidp = nfsrv_defaultgid;
|
||||
NFSUNLOCKNAMEID();
|
||||
return (0);
|
||||
error = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
LIST_FOREACH(usrp, NFSGROUPNAMEHASH(str, len), lug_namehash) {
|
||||
@ -2799,7 +2843,8 @@ nfsv4_strtogid(u_char *str, int len, gid_t *gidp, NFSPROC_T *p)
|
||||
TAILQ_REMOVE(&nfsuserlruhead, usrp, lug_lru);
|
||||
TAILQ_INSERT_TAIL(&nfsuserlruhead, usrp, lug_lru);
|
||||
NFSUNLOCKNAMEID();
|
||||
return (0);
|
||||
error = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
NFSUNLOCKNAMEID();
|
||||
@ -2808,7 +2853,11 @@ nfsv4_strtogid(u_char *str, int len, gid_t *gidp, NFSPROC_T *p)
|
||||
str, p);
|
||||
if (ret == 0 && cnt < 2)
|
||||
goto tryagain;
|
||||
return (NFSERR_BADOWNER);
|
||||
error = NFSERR_BADOWNER;
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2853,7 +2902,8 @@ nfsrv_nfsuserdport(u_short port, NFSPROC_T *p)
|
||||
NFSLOCKNAMEID();
|
||||
if (nfsrv_nfsuserd) {
|
||||
NFSUNLOCKNAMEID();
|
||||
return (EPERM);
|
||||
error = EPERM;
|
||||
goto out;
|
||||
}
|
||||
nfsrv_nfsuserd = 1;
|
||||
NFSUNLOCKNAMEID();
|
||||
@ -2879,6 +2929,8 @@ nfsrv_nfsuserdport(u_short port, NFSPROC_T *p)
|
||||
NFSSOCKADDRFREE(rp->nr_nam);
|
||||
nfsrv_nfsuserd = 0;
|
||||
}
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -2918,7 +2970,8 @@ nfsrv_getuser(int procnum, uid_t uid, gid_t gid, char *name, NFSPROC_T *p)
|
||||
NFSLOCKNAMEID();
|
||||
if (nfsrv_nfsuserd == 0) {
|
||||
NFSUNLOCKNAMEID();
|
||||
return (EPERM);
|
||||
error = EPERM;
|
||||
goto out;
|
||||
}
|
||||
NFSUNLOCKNAMEID();
|
||||
nd = &nfsd;
|
||||
@ -2944,6 +2997,8 @@ nfsrv_getuser(int procnum, uid_t uid, gid_t gid, char *name, NFSPROC_T *p)
|
||||
mbuf_freem(nd->nd_mrep);
|
||||
error = nd->nd_repstat;
|
||||
}
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -3000,7 +3055,7 @@ nfssvc_idname(struct nfsd_idargs *nidp)
|
||||
NFSUNLOCKNAMEID();
|
||||
if (error)
|
||||
free(cp, M_NFSSTRING);
|
||||
return (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3013,7 +3068,7 @@ nfssvc_idname(struct nfsd_idargs *nidp)
|
||||
nidp->nid_namelen);
|
||||
if (error) {
|
||||
free((caddr_t)newusrp, M_NFSUSERGROUP);
|
||||
return (error);
|
||||
goto out;
|
||||
}
|
||||
newusrp->lug_namelen = nidp->nid_namelen;
|
||||
|
||||
@ -3088,6 +3143,8 @@ nfssvc_idname(struct nfsd_idargs *nidp)
|
||||
} else
|
||||
FREE((caddr_t)newusrp, M_NFSUSERGROUP);
|
||||
NFSUNLOCKNAMEID();
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -3117,6 +3174,7 @@ nfsrv_checkutf8(u_int8_t *cp, int len)
|
||||
int cnt = 0, gotd = 0, shift = 0;
|
||||
u_int8_t byte;
|
||||
static int utf8_shift[5] = { 7, 11, 16, 21, 26 };
|
||||
int error = 0;
|
||||
|
||||
/*
|
||||
* Here are what the variables are used for:
|
||||
@ -3133,14 +3191,18 @@ nfsrv_checkutf8(u_int8_t *cp, int len)
|
||||
if (cnt > 0) {
|
||||
/* This handles the 10xxxxxx bytes */
|
||||
if ((*cp & 0xc0) != 0x80 ||
|
||||
(gotd && (*cp & 0x20)))
|
||||
return (NFSERR_INVAL);
|
||||
(gotd && (*cp & 0x20))) {
|
||||
error = NFSERR_INVAL;
|
||||
goto out;
|
||||
}
|
||||
gotd = 0;
|
||||
val <<= 6;
|
||||
val |= (*cp & 0x3f);
|
||||
cnt--;
|
||||
if (cnt == 0 && (val >> shift) == 0x0)
|
||||
return (NFSERR_INVAL);
|
||||
if (cnt == 0 && (val >> shift) == 0x0) {
|
||||
error = NFSERR_INVAL;
|
||||
goto out;
|
||||
}
|
||||
} else if (*cp & 0x80) {
|
||||
/* first byte of multi byte char */
|
||||
byte = *cp;
|
||||
@ -3148,8 +3210,10 @@ nfsrv_checkutf8(u_int8_t *cp, int len)
|
||||
cnt++;
|
||||
byte <<= 1;
|
||||
}
|
||||
if (cnt == 0 || cnt == 6)
|
||||
return (NFSERR_INVAL);
|
||||
if (cnt == 0 || cnt == 6) {
|
||||
error = NFSERR_INVAL;
|
||||
goto out;
|
||||
}
|
||||
val = (*cp & (0x3f >> cnt));
|
||||
shift = utf8_shift[cnt - 1];
|
||||
if (cnt == 2 && val == 0xd)
|
||||
@ -3160,8 +3224,11 @@ nfsrv_checkutf8(u_int8_t *cp, int len)
|
||||
len--;
|
||||
}
|
||||
if (cnt > 0)
|
||||
return (NFSERR_INVAL);
|
||||
return (0);
|
||||
error = NFSERR_INVAL;
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3182,7 +3249,7 @@ nfsrv_getrefstr(struct nfsrv_descript *nd, u_char **fsrootp, u_char **srvp,
|
||||
{
|
||||
u_int32_t *tl;
|
||||
u_char *cp = NULL, *cp2 = NULL, *cp3, *str;
|
||||
int i, j, len, stringlen, cnt, slen, siz, xdrsum, error, nsrv;
|
||||
int i, j, len, stringlen, cnt, slen, siz, xdrsum, error = 0, nsrv;
|
||||
struct list {
|
||||
SLIST_ENTRY(list) next;
|
||||
int len;
|
||||
@ -3200,15 +3267,20 @@ nfsrv_getrefstr(struct nfsrv_descript *nd, u_char **fsrootp, u_char **srvp,
|
||||
*/
|
||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||
len = fxdr_unsigned(int, *tl);
|
||||
if (len < 0 || len > 10240)
|
||||
return (NFSERR_BADXDR);
|
||||
if (len < 0 || len > 10240) {
|
||||
error = NFSERR_BADXDR;
|
||||
goto nfsmout;
|
||||
}
|
||||
if (len == 0) {
|
||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||
if (*tl != 0)
|
||||
return (NFSERR_BADXDR);
|
||||
if (*tl != 0) {
|
||||
error = NFSERR_BADXDR;
|
||||
goto nfsmout;
|
||||
}
|
||||
*nilp = 1;
|
||||
*sump = 2 * NFSX_UNSIGNED;
|
||||
return (0);
|
||||
error = 0;
|
||||
goto nfsmout;
|
||||
}
|
||||
cp = malloc(len + 1, M_NFSSTRING, M_WAITOK);
|
||||
error = nfsrv_mtostr(nd, cp, len);
|
||||
@ -3218,10 +3290,8 @@ nfsrv_getrefstr(struct nfsrv_descript *nd, u_char **fsrootp, u_char **srvp,
|
||||
if (cnt <= 0)
|
||||
error = NFSERR_BADXDR;
|
||||
}
|
||||
if (error) {
|
||||
free(cp, M_NFSSTRING);
|
||||
return (error);
|
||||
}
|
||||
if (error)
|
||||
goto nfsmout;
|
||||
|
||||
/*
|
||||
* Now, loop through the location list and make up the srvlist.
|
||||
@ -3235,9 +3305,8 @@ nfsrv_getrefstr(struct nfsrv_descript *nd, u_char **fsrootp, u_char **srvp,
|
||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||
nsrv = fxdr_unsigned(int, *tl);
|
||||
if (nsrv <= 0) {
|
||||
free(cp, M_NFSSTRING);
|
||||
free(cp2, M_NFSSTRING);
|
||||
return (NFSERR_BADXDR);
|
||||
error = NFSERR_BADXDR;
|
||||
goto nfsmout;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3246,9 +3315,8 @@ nfsrv_getrefstr(struct nfsrv_descript *nd, u_char **fsrootp, u_char **srvp,
|
||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||
len = fxdr_unsigned(int, *tl);
|
||||
if (len <= 0 || len > 1024) {
|
||||
free(cp, M_NFSSTRING);
|
||||
free(cp2, M_NFSSTRING);
|
||||
return (NFSERR_BADXDR);
|
||||
error = NFSERR_BADXDR;
|
||||
goto nfsmout;
|
||||
}
|
||||
nfsrv_refstrbigenough(siz + len + 3, &cp2, &cp3, &slen);
|
||||
if (cp3 != cp2) {
|
||||
@ -3256,11 +3324,8 @@ nfsrv_getrefstr(struct nfsrv_descript *nd, u_char **fsrootp, u_char **srvp,
|
||||
siz++;
|
||||
}
|
||||
error = nfsrv_mtostr(nd, cp3, len);
|
||||
if (error) {
|
||||
free(cp, M_NFSSTRING);
|
||||
free(cp2, M_NFSSTRING);
|
||||
return (error);
|
||||
}
|
||||
if (error)
|
||||
goto nfsmout;
|
||||
cp3 += len;
|
||||
*cp3++ = ':';
|
||||
siz += (len + 1);
|
||||
@ -3272,18 +3337,14 @@ nfsrv_getrefstr(struct nfsrv_descript *nd, u_char **fsrootp, u_char **srvp,
|
||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||
len = fxdr_unsigned(int, *tl);
|
||||
if (len <= 0 || len > 1024) {
|
||||
free(cp, M_NFSSTRING);
|
||||
free(cp2, M_NFSSTRING);
|
||||
return (NFSERR_BADXDR);
|
||||
error = NFSERR_BADXDR;
|
||||
goto nfsmout;
|
||||
}
|
||||
lsp = (struct list *)malloc(sizeof (struct list)
|
||||
+ len, M_TEMP, M_WAITOK);
|
||||
error = nfsrv_mtostr(nd, lsp->host, len);
|
||||
if (error) {
|
||||
free(cp, M_NFSSTRING);
|
||||
free(cp2, M_NFSSTRING);
|
||||
return (error);
|
||||
}
|
||||
if (error)
|
||||
goto nfsmout;
|
||||
xdrsum += NFSX_UNSIGNED + NFSM_RNDUP(len);
|
||||
lsp->len = len;
|
||||
SLIST_INSERT_HEAD(&head, lsp, next);
|
||||
@ -3295,17 +3356,13 @@ nfsrv_getrefstr(struct nfsrv_descript *nd, u_char **fsrootp, u_char **srvp,
|
||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||
len = fxdr_unsigned(int, *tl);
|
||||
if (len <= 0 || len > 1024) {
|
||||
free(cp, M_NFSSTRING);
|
||||
free(cp2, M_NFSSTRING);
|
||||
return (NFSERR_BADXDR);
|
||||
error = NFSERR_BADXDR;
|
||||
goto nfsmout;
|
||||
}
|
||||
nfsrv_refstrbigenough(siz + len + 1, &cp2, &cp3, &slen);
|
||||
error = nfsrv_mtostr(nd, cp3, len);
|
||||
if (error) {
|
||||
free(cp, M_NFSSTRING);
|
||||
free(cp2, M_NFSSTRING);
|
||||
return (error);
|
||||
}
|
||||
if (error)
|
||||
goto nfsmout;
|
||||
xdrsum += NFSX_UNSIGNED + NFSM_RNDUP(len);
|
||||
str = cp3;
|
||||
stringlen = len;
|
||||
@ -3328,12 +3385,14 @@ nfsrv_getrefstr(struct nfsrv_descript *nd, u_char **fsrootp, u_char **srvp,
|
||||
*fsrootp = cp;
|
||||
*srvp = cp2;
|
||||
*sump = xdrsum;
|
||||
NFSEXITCODE2(0, nd);
|
||||
return (0);
|
||||
nfsmout:
|
||||
if (cp != NULL)
|
||||
free(cp, M_NFSSTRING);
|
||||
if (cp2 != NULL)
|
||||
free(cp2, M_NFSSTRING);
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,22 @@ struct nfsexstuff {
|
||||
int nes_secflavors[MAXSECFLAVORS]; /* and the flavors */
|
||||
};
|
||||
|
||||
/*
|
||||
* These are NO-OPS for BSD until Isilon upstreams EXITCODE support.
|
||||
* EXITCODE is an in-memory ring buffer that holds the routines failing status.
|
||||
* This is a valuable tool to use when debugging and analyzing issues.
|
||||
* In addition to recording a routine's failing status, it offers
|
||||
* logging of routines for call stack tracing.
|
||||
* EXITCODE should be used only in routines that return a true errno value, as
|
||||
* that value will be formatted to a displayable errno string. Routines that
|
||||
* return regular int status that are not true errno should not set EXITCODE.
|
||||
* If you want to log routine tracing, you can add EXITCODE(0) to any routine.
|
||||
* NFS extended the EXITCODE with EXITCODE2 to record either the routine's
|
||||
* exit errno status or the nd_repstat.
|
||||
*/
|
||||
#define NFSEXITCODE(error)
|
||||
#define NFSEXITCODE2(error, nd)
|
||||
|
||||
#define NFSVNO_EXINIT(e) ((e)->nes_exflag = 0)
|
||||
#define NFSVNO_EXPORTED(e) ((e)->nes_exflag & MNT_EXPORTED)
|
||||
#define NFSVNO_EXRDONLY(e) ((e)->nes_exflag & MNT_EXRDONLY)
|
||||
|
@ -308,6 +308,7 @@ nfsrvd_getcache(struct nfsrv_descript *nd, struct socket *so)
|
||||
ret = nfsrc_gettcp(nd, newrp);
|
||||
}
|
||||
nfsrc_trimcache(nd->nd_sockref, so);
|
||||
NFSEXITCODE2(0, nd);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -373,7 +374,7 @@ nfsrc_getudp(struct nfsrv_descript *nd, struct nfsrvcache *newrp)
|
||||
}
|
||||
nfsrc_unlock(rp);
|
||||
free((caddr_t)newrp, M_NFSRVCACHE);
|
||||
return (ret);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
newnfsstats.srvcache_misses++;
|
||||
@ -394,7 +395,11 @@ nfsrc_getudp(struct nfsrv_descript *nd, struct nfsrvcache *newrp)
|
||||
TAILQ_INSERT_TAIL(&nfsrvudplru, newrp, rc_lru);
|
||||
NFSUNLOCKCACHE();
|
||||
nd->nd_rp = newrp;
|
||||
return (RC_DOIT);
|
||||
ret = RC_DOIT;
|
||||
|
||||
out:
|
||||
NFSEXITCODE2(0, nd);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -436,8 +441,7 @@ nfsrvd_updatecache(struct nfsrv_descript *nd, struct socket *so)
|
||||
M_COPYALL, M_WAIT);
|
||||
rp->rc_timestamp = NFSD_MONOSEC + NFSRVCACHE_TCPTIMEOUT;
|
||||
nfsrc_unlock(rp);
|
||||
nfsrc_trimcache(nd->nd_sockref, so);
|
||||
return (retrp);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -492,7 +496,10 @@ nfsrvd_updatecache(struct nfsrv_descript *nd, struct socket *so)
|
||||
nfsrc_freecache(rp);
|
||||
NFSUNLOCKCACHE();
|
||||
}
|
||||
|
||||
out:
|
||||
nfsrc_trimcache(nd->nd_sockref, so);
|
||||
NFSEXITCODE2(0, nd);
|
||||
return (retrp);
|
||||
}
|
||||
|
||||
@ -656,7 +663,7 @@ nfsrc_gettcp(struct nfsrv_descript *nd, struct nfsrvcache *newrp)
|
||||
}
|
||||
nfsrc_unlock(rp);
|
||||
free((caddr_t)newrp, M_NFSRVCACHE);
|
||||
return (ret);
|
||||
goto out;
|
||||
}
|
||||
newnfsstats.srvcache_misses++;
|
||||
newnfsstats.srvcache_size++;
|
||||
@ -670,7 +677,11 @@ nfsrc_gettcp(struct nfsrv_descript *nd, struct nfsrvcache *newrp)
|
||||
LIST_INSERT_HEAD(hp, newrp, rc_hash);
|
||||
NFSUNLOCKCACHE();
|
||||
nd->nd_rp = newrp;
|
||||
return (RC_DOIT);
|
||||
ret = RC_DOIT;
|
||||
|
||||
out:
|
||||
NFSEXITCODE2(0, nd);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -115,7 +115,7 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt)
|
||||
if (rqst->rq_proc > NFSV2PROC_STATFS) {
|
||||
svcerr_noproc(rqst);
|
||||
svc_freereq(rqst);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
nd.nd_procnum = newnfs_nfsv3_procid[rqst->rq_proc];
|
||||
nd.nd_flag = ND_NFSV2;
|
||||
@ -123,7 +123,7 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt)
|
||||
if (rqst->rq_proc >= NFS_V3NPROCS) {
|
||||
svcerr_noproc(rqst);
|
||||
svc_freereq(rqst);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
nd.nd_procnum = rqst->rq_proc;
|
||||
nd.nd_flag = ND_NFSV3;
|
||||
@ -132,7 +132,7 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt)
|
||||
rqst->rq_proc != NFSV4PROC_COMPOUND) {
|
||||
svcerr_noproc(rqst);
|
||||
svc_freereq(rqst);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
nd.nd_procnum = rqst->rq_proc;
|
||||
nd.nd_flag = ND_NFSV4;
|
||||
@ -192,7 +192,7 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt)
|
||||
svcerr_weakauth(rqst);
|
||||
svc_freereq(rqst);
|
||||
m_freem(nd.nd_mrep);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@ -201,7 +201,7 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt)
|
||||
svcerr_weakauth(rqst);
|
||||
svc_freereq(rqst);
|
||||
m_freem(nd.nd_mrep);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Set the flag based on credflavor */
|
||||
@ -215,7 +215,7 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt)
|
||||
svcerr_weakauth(rqst);
|
||||
svc_freereq(rqst);
|
||||
m_freem(nd.nd_mrep);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef MAC
|
||||
@ -227,7 +227,7 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt)
|
||||
svcerr_weakauth(rqst);
|
||||
svc_freereq(rqst);
|
||||
m_freem(nd.nd_mrep);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@ -248,13 +248,13 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt)
|
||||
if (nd.nd_mreq != NULL)
|
||||
m_freem(nd.nd_mreq);
|
||||
svc_freereq(rqst);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nd.nd_mreq == NULL) {
|
||||
svcerr_decode(rqst);
|
||||
svc_freereq(rqst);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nd.nd_repstat & NFSERR_AUTHERR) {
|
||||
@ -267,6 +267,9 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt)
|
||||
if (rp != NULL)
|
||||
nfsrvd_sentcache(rp, xprt->xp_socket, 0);
|
||||
svc_freereq(rqst);
|
||||
|
||||
out:
|
||||
NFSEXITCODE(0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -329,6 +332,8 @@ nfs_proc(struct nfsrv_descript *nd, u_int32_t xid, struct socket *so,
|
||||
cacherep = RC_REPLY;
|
||||
*rpp = nfsrvd_updatecache(nd, so);
|
||||
}
|
||||
|
||||
NFSEXITCODE2(0, nd);
|
||||
return (cacherep);
|
||||
}
|
||||
|
||||
@ -340,7 +345,7 @@ nfsrvd_addsock(struct file *fp)
|
||||
{
|
||||
int siz;
|
||||
struct socket *so;
|
||||
int error;
|
||||
int error = 0;
|
||||
SVCXPRT *xprt;
|
||||
static u_int64_t sockref = 0;
|
||||
|
||||
@ -348,9 +353,8 @@ nfsrvd_addsock(struct file *fp)
|
||||
|
||||
siz = sb_max_adj;
|
||||
error = soreserve(so, siz, siz);
|
||||
if (error) {
|
||||
return (error);
|
||||
}
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Steal the socket from userland so that it doesn't close
|
||||
@ -376,7 +380,9 @@ nfsrvd_addsock(struct file *fp)
|
||||
SVC_RELEASE(xprt);
|
||||
}
|
||||
|
||||
return (0);
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -387,13 +393,13 @@ int
|
||||
nfsrvd_nfsd(struct thread *td, struct nfsd_nfsd_args *args)
|
||||
{
|
||||
char principal[MAXHOSTNAMELEN + 5];
|
||||
int error;
|
||||
int error = 0;
|
||||
bool_t ret2, ret3, ret4;
|
||||
|
||||
error = copyinstr(args->principal, principal, sizeof (principal),
|
||||
NULL);
|
||||
if (error)
|
||||
return (error);
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Only the first nfsd actually does any work. The RPC code
|
||||
@ -438,7 +444,9 @@ nfsrvd_nfsd(struct thread *td, struct nfsd_nfsd_args *args)
|
||||
}
|
||||
NFSD_UNLOCK();
|
||||
|
||||
return (0);
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -124,6 +124,8 @@ nfsvno_getattr(struct vnode *vp, struct nfsvattr *nvap, struct ucred *cred,
|
||||
error = VOP_GETATTR(vp, &nvap->na_vattr, cred);
|
||||
if (lockedit != 0)
|
||||
NFSVOPUNLOCK(vp, 0);
|
||||
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -138,6 +140,8 @@ nfsvno_getfh(struct vnode *vp, fhandle_t *fhp, struct thread *p)
|
||||
NFSBZERO((caddr_t)fhp, sizeof(fhandle_t));
|
||||
fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid;
|
||||
error = VOP_VPTOFH(vp, &fhp->fh_fid);
|
||||
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -160,8 +164,10 @@ nfsvno_accchk(struct vnode *vp, accmode_t accmode, struct ucred *cred,
|
||||
int error = 0, getret = 0;
|
||||
|
||||
if (vpislocked == 0) {
|
||||
if (NFSVOPLOCK(vp, LK_SHARED) != 0)
|
||||
return (EPERM);
|
||||
if (NFSVOPLOCK(vp, LK_SHARED) != 0) {
|
||||
error = EPERM;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (accmode & VWRITE) {
|
||||
/* Just vn_writechk() changed to check rdonly */
|
||||
@ -192,7 +198,7 @@ nfsvno_accchk(struct vnode *vp, accmode_t accmode, struct ucred *cred,
|
||||
if (error != 0) {
|
||||
if (vpislocked == 0)
|
||||
NFSVOPUNLOCK(vp, 0);
|
||||
return (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -232,6 +238,9 @@ nfsvno_accchk(struct vnode *vp, accmode_t accmode, struct ucred *cred,
|
||||
}
|
||||
if (vpislocked == 0)
|
||||
NFSVOPUNLOCK(vp, 0);
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -245,6 +254,7 @@ nfsvno_setattr(struct vnode *vp, struct nfsvattr *nvap, struct ucred *cred,
|
||||
int error;
|
||||
|
||||
error = VOP_SETATTR(vp, &nvap->na_vattr, cred);
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -279,7 +289,8 @@ nfsvno_namei(struct nfsrv_descript *nd, struct nameidata *ndp,
|
||||
else
|
||||
vrele(dp);
|
||||
nfsvno_relpathbuf(ndp);
|
||||
return (ENOTDIR);
|
||||
error = ENOTDIR;
|
||||
goto out1;
|
||||
}
|
||||
if (islocked)
|
||||
NFSVOPUNLOCK(dp, 0);
|
||||
@ -444,6 +455,9 @@ nfsvno_namei(struct nfsrv_descript *nd, struct nameidata *ndp,
|
||||
} else if ((ndp->ni_cnd.cn_flags & (WANTPARENT|LOCKPARENT)) == 0) {
|
||||
ndp->ni_dvp = NULL;
|
||||
}
|
||||
|
||||
out1:
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -487,7 +501,7 @@ nfsvno_readlink(struct vnode *vp, struct ucred *cred, struct thread *p,
|
||||
struct iovec *ivp = iv;
|
||||
struct uio io, *uiop = &io;
|
||||
struct mbuf *mp, *mp2 = NULL, *mp3 = NULL;
|
||||
int i, len, tlen, error;
|
||||
int i, len, tlen, error = 0;
|
||||
|
||||
len = 0;
|
||||
i = 0;
|
||||
@ -523,7 +537,7 @@ nfsvno_readlink(struct vnode *vp, struct ucred *cred, struct thread *p,
|
||||
if (error) {
|
||||
m_freem(mp3);
|
||||
*lenp = 0;
|
||||
return (error);
|
||||
goto out;
|
||||
}
|
||||
if (uiop->uio_resid > 0) {
|
||||
len -= uiop->uio_resid;
|
||||
@ -533,7 +547,10 @@ nfsvno_readlink(struct vnode *vp, struct ucred *cred, struct thread *p,
|
||||
*lenp = len;
|
||||
*mpp = mp3;
|
||||
*mpendp = mp;
|
||||
return (0);
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -650,7 +667,7 @@ nfsvno_read(struct vnode *vp, off_t off, int cnt, struct ucred *cred,
|
||||
if (error) {
|
||||
m_freem(m3);
|
||||
*mpp = NULL;
|
||||
return (error);
|
||||
goto out;
|
||||
}
|
||||
tlen = len - uiop->uio_resid;
|
||||
cnt = cnt < tlen ? cnt : tlen;
|
||||
@ -662,7 +679,10 @@ nfsvno_read(struct vnode *vp, off_t off, int cnt, struct ucred *cred,
|
||||
nfsrv_adj(m3, len - tlen, tlen - cnt);
|
||||
*mpp = m3;
|
||||
*mpendp = m2;
|
||||
return (0);
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -712,6 +732,8 @@ nfsvno_write(struct vnode *vp, off_t off, int retlen, int cnt, int stable,
|
||||
uiop->uio_offset = off;
|
||||
error = VOP_WRITE(vp, uiop, ioflags, cred);
|
||||
FREE((caddr_t)iv, M_TEMP);
|
||||
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -758,7 +780,7 @@ nfsvno_createsub(struct nfsrv_descript *nd, struct nameidata *ndp,
|
||||
vrele(ndp->ni_startdir);
|
||||
nfsvno_relpathbuf(ndp);
|
||||
vput(ndp->ni_dvp);
|
||||
return (error);
|
||||
goto out;
|
||||
}
|
||||
nvap->na_rdev = rdev;
|
||||
error = VOP_MKNOD(ndp->ni_dvp, &ndp->ni_vp,
|
||||
@ -767,12 +789,13 @@ nfsvno_createsub(struct nfsrv_descript *nd, struct nameidata *ndp,
|
||||
nfsvno_relpathbuf(ndp);
|
||||
vrele(ndp->ni_startdir);
|
||||
if (error)
|
||||
return (error);
|
||||
goto out;
|
||||
} else {
|
||||
vrele(ndp->ni_startdir);
|
||||
nfsvno_relpathbuf(ndp);
|
||||
vput(ndp->ni_dvp);
|
||||
return (ENXIO);
|
||||
error = ENXIO;
|
||||
goto out;
|
||||
}
|
||||
*vpp = ndp->ni_vp;
|
||||
} else {
|
||||
@ -804,6 +827,9 @@ nfsvno_createsub(struct nfsrv_descript *nd, struct nameidata *ndp,
|
||||
if (error)
|
||||
vput(*vpp);
|
||||
}
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -826,13 +852,15 @@ nfsvno_mknod(struct nameidata *ndp, struct nfsvattr *nvap, struct ucred *cred,
|
||||
nfsvno_relpathbuf(ndp);
|
||||
vput(ndp->ni_dvp);
|
||||
vrele(ndp->ni_vp);
|
||||
return (EEXIST);
|
||||
error = EEXIST;
|
||||
goto out;
|
||||
}
|
||||
if (vtyp != VCHR && vtyp != VBLK && vtyp != VSOCK && vtyp != VFIFO) {
|
||||
vrele(ndp->ni_startdir);
|
||||
nfsvno_relpathbuf(ndp);
|
||||
vput(ndp->ni_dvp);
|
||||
return (NFSERR_BADTYPE);
|
||||
error = NFSERR_BADTYPE;
|
||||
goto out;
|
||||
}
|
||||
if (vtyp == VSOCK) {
|
||||
vrele(ndp->ni_startdir);
|
||||
@ -846,7 +874,7 @@ nfsvno_mknod(struct nameidata *ndp, struct nfsvattr *nvap, struct ucred *cred,
|
||||
vrele(ndp->ni_startdir);
|
||||
nfsvno_relpathbuf(ndp);
|
||||
vput(ndp->ni_dvp);
|
||||
return (error);
|
||||
goto out;
|
||||
}
|
||||
error = VOP_MKNOD(ndp->ni_dvp, &ndp->ni_vp,
|
||||
&ndp->ni_cnd, &nvap->na_vattr);
|
||||
@ -858,6 +886,9 @@ nfsvno_mknod(struct nameidata *ndp, struct nfsvattr *nvap, struct ucred *cred,
|
||||
* see any reason to do the lookup.
|
||||
*/
|
||||
}
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -877,12 +908,16 @@ nfsvno_mkdir(struct nameidata *ndp, struct nfsvattr *nvap, uid_t saved_uid,
|
||||
vput(ndp->ni_dvp);
|
||||
vrele(ndp->ni_vp);
|
||||
nfsvno_relpathbuf(ndp);
|
||||
return (EEXIST);
|
||||
error = EEXIST;
|
||||
goto out;
|
||||
}
|
||||
error = VOP_MKDIR(ndp->ni_dvp, &ndp->ni_vp, &ndp->ni_cnd,
|
||||
&nvap->na_vattr);
|
||||
vput(ndp->ni_dvp);
|
||||
nfsvno_relpathbuf(ndp);
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -904,7 +939,8 @@ nfsvno_symlink(struct nameidata *ndp, struct nfsvattr *nvap, char *pathcp,
|
||||
else
|
||||
vput(ndp->ni_dvp);
|
||||
vrele(ndp->ni_vp);
|
||||
return (EEXIST);
|
||||
error = EEXIST;
|
||||
goto out;
|
||||
}
|
||||
|
||||
error = VOP_SYMLINK(ndp->ni_dvp, &ndp->ni_vp, &ndp->ni_cnd,
|
||||
@ -920,6 +956,9 @@ nfsvno_symlink(struct nameidata *ndp, struct nfsvattr *nvap, char *pathcp,
|
||||
*/
|
||||
if (!not_v2 && !error)
|
||||
vput(ndp->ni_vp);
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -960,10 +999,12 @@ nfsvno_getsymlink(struct nfsrv_descript *nd, struct nfsvattr *nvap,
|
||||
}
|
||||
*pathcpp = pathcp;
|
||||
*lenp = len;
|
||||
NFSEXITCODE2(0, nd);
|
||||
return (0);
|
||||
nfsmout:
|
||||
if (pathcp)
|
||||
free(pathcp, M_TEMP);
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -989,6 +1030,7 @@ nfsvno_removesub(struct nameidata *ndp, int is_v4, struct ucred *cred,
|
||||
else
|
||||
vput(ndp->ni_dvp);
|
||||
vput(vp);
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -1027,6 +1069,7 @@ nfsvno_rmdirsub(struct nameidata *ndp, int is_v4, struct ucred *cred,
|
||||
else
|
||||
vput(ndp->ni_dvp);
|
||||
vput(vp);
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -1136,6 +1179,7 @@ nfsvno_rename(struct nameidata *fromndp, struct nameidata *tondp,
|
||||
out1:
|
||||
vrele(fromndp->ni_startdir);
|
||||
nfsvno_relpathbuf(fromndp);
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -1177,6 +1221,7 @@ nfsvno_link(struct nameidata *ndp, struct vnode *vp, struct ucred *cred,
|
||||
vrele(ndp->ni_vp);
|
||||
}
|
||||
nfsvno_relpathbuf(ndp);
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -1271,6 +1316,7 @@ nfsvno_fsync(struct vnode *vp, u_int64_t off, int cnt, struct ucred *cred,
|
||||
}
|
||||
BO_UNLOCK(bo);
|
||||
}
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -1296,6 +1342,7 @@ nfsvno_statfs(struct vnode *vp, struct statfs *sf)
|
||||
if (sf->f_ffree < 0)
|
||||
sf->f_ffree = 0;
|
||||
}
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -1386,6 +1433,8 @@ nfsvno_open(struct nfsrv_descript *nd, struct nameidata *ndp,
|
||||
}
|
||||
}
|
||||
*vpp = vp;
|
||||
|
||||
NFSEXITCODE2(0, nd);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1419,6 +1468,7 @@ nfsvno_fillattr(struct nfsrv_descript *nd, struct mount *mp, struct vnode *vp,
|
||||
error = nfsv4_fillattr(nd, mp, vp, NULL, &nvap->na_vattr, fhp, rderror,
|
||||
attrbitp, cred, p, isdgram, reterr, supports_nfsv4acls, at_root,
|
||||
mounted_on_fileno);
|
||||
NFSEXITCODE2(0, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -1465,7 +1515,7 @@ nfsrvd_readdir(struct nfsrv_descript *nd, int isdgram,
|
||||
|
||||
if (nd->nd_repstat) {
|
||||
nfsrv_postopattr(nd, getret, &at);
|
||||
return (0);
|
||||
goto out;
|
||||
}
|
||||
if (nd->nd_flag & ND_NFSV2) {
|
||||
NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
|
||||
@ -1512,7 +1562,7 @@ nfsrvd_readdir(struct nfsrv_descript *nd, int isdgram,
|
||||
vput(vp);
|
||||
if (nd->nd_flag & ND_NFSV3)
|
||||
nfsrv_postopattr(nd, getret, &at);
|
||||
return (0);
|
||||
goto out;
|
||||
}
|
||||
not_zfs = strcmp(vp->v_mount->mnt_vfc->vfc_name, "zfs");
|
||||
MALLOC(rbuf, caddr_t, siz, M_TEMP, M_WAITOK);
|
||||
@ -1556,7 +1606,7 @@ nfsrvd_readdir(struct nfsrv_descript *nd, int isdgram,
|
||||
free((caddr_t)cookies, M_TEMP);
|
||||
if (nd->nd_flag & ND_NFSV3)
|
||||
nfsrv_postopattr(nd, getret, &at);
|
||||
return (0);
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* If nothing read, return eof
|
||||
@ -1576,7 +1626,7 @@ nfsrvd_readdir(struct nfsrv_descript *nd, int isdgram,
|
||||
*tl = newnfs_true;
|
||||
FREE((caddr_t)rbuf, M_TEMP);
|
||||
FREE((caddr_t)cookies, M_TEMP);
|
||||
return (0);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1677,9 +1727,13 @@ nfsrvd_readdir(struct nfsrv_descript *nd, int isdgram,
|
||||
*tl = newnfs_false;
|
||||
FREE((caddr_t)rbuf, M_TEMP);
|
||||
FREE((caddr_t)cookies, M_TEMP);
|
||||
|
||||
out:
|
||||
NFSEXITCODE2(0, nd);
|
||||
return (0);
|
||||
nfsmout:
|
||||
vput(vp);
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -1714,7 +1768,7 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram,
|
||||
|
||||
if (nd->nd_repstat) {
|
||||
nfsrv_postopattr(nd, getret, &at);
|
||||
return (0);
|
||||
goto out;
|
||||
}
|
||||
NFSM_DISSECT(tl, u_int32_t *, 6 * NFSX_UNSIGNED);
|
||||
off = fxdr_hyper(tl);
|
||||
@ -1786,7 +1840,7 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram,
|
||||
vput(vp);
|
||||
if (nd->nd_flag & ND_NFSV3)
|
||||
nfsrv_postopattr(nd, getret, &at);
|
||||
return (0);
|
||||
goto out;
|
||||
}
|
||||
not_zfs = strcmp(vp->v_mount->mnt_vfc->vfc_name, "zfs");
|
||||
|
||||
@ -1826,7 +1880,7 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram,
|
||||
free((caddr_t)rbuf, M_TEMP);
|
||||
if (nd->nd_flag & ND_NFSV3)
|
||||
nfsrv_postopattr(nd, getret, &at);
|
||||
return (0);
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* If nothing read, return eof
|
||||
@ -1843,7 +1897,7 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram,
|
||||
*tl = newnfs_true;
|
||||
free((caddr_t)cookies, M_TEMP);
|
||||
free((caddr_t)rbuf, M_TEMP);
|
||||
return (0);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1896,7 +1950,7 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram,
|
||||
free(rbuf, M_TEMP);
|
||||
if (nd->nd_flag & ND_NFSV3)
|
||||
nfsrv_postopattr(nd, getret, &at);
|
||||
return (0);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2148,9 +2202,13 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram,
|
||||
}
|
||||
FREE((caddr_t)cookies, M_TEMP);
|
||||
FREE((caddr_t)rbuf, M_TEMP);
|
||||
|
||||
out:
|
||||
NFSEXITCODE2(0, nd);
|
||||
return (0);
|
||||
nfsmout:
|
||||
vput(vp);
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -2249,6 +2307,7 @@ nfsrv_sattr(struct nfsrv_descript *nd, struct nfsvattr *nvap,
|
||||
error = nfsv4_sattr(nd, nvap, attrbitp, aclp, p);
|
||||
};
|
||||
nfsmout:
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -2272,7 +2331,7 @@ nfsv4_sattr(struct nfsrv_descript *nd, struct nfsvattr *nvap,
|
||||
|
||||
error = nfsrv_getattrbits(nd, attrbitp, NULL, &retnotsup);
|
||||
if (error)
|
||||
return (error);
|
||||
goto nfsmout;
|
||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||
attrsize = fxdr_unsigned(int, *tl);
|
||||
|
||||
@ -2337,8 +2396,10 @@ nfsv4_sattr(struct nfsrv_descript *nd, struct nfsvattr *nvap,
|
||||
case NFSATTRBIT_OWNER:
|
||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||
j = fxdr_unsigned(int, *tl);
|
||||
if (j < 0)
|
||||
return (NFSERR_BADXDR);
|
||||
if (j < 0) {
|
||||
error = NFSERR_BADXDR;
|
||||
goto nfsmout;
|
||||
}
|
||||
if (j > NFSV4_SMALLSTR)
|
||||
cp = malloc(j + 1, M_NFSSTRING, M_WAITOK);
|
||||
else
|
||||
@ -2347,7 +2408,7 @@ nfsv4_sattr(struct nfsrv_descript *nd, struct nfsvattr *nvap,
|
||||
if (error) {
|
||||
if (j > NFSV4_SMALLSTR)
|
||||
free(cp, M_NFSSTRING);
|
||||
return (error);
|
||||
goto nfsmout;
|
||||
}
|
||||
if (!nd->nd_repstat) {
|
||||
nd->nd_repstat = nfsv4_strtouid(cp,j,&uid,p);
|
||||
@ -2361,8 +2422,10 @@ nfsv4_sattr(struct nfsrv_descript *nd, struct nfsvattr *nvap,
|
||||
case NFSATTRBIT_OWNERGROUP:
|
||||
NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||
j = fxdr_unsigned(int, *tl);
|
||||
if (j < 0)
|
||||
return (NFSERR_BADXDR);
|
||||
if (j < 0) {
|
||||
error = NFSERR_BADXDR;
|
||||
goto nfsmout;
|
||||
}
|
||||
if (j > NFSV4_SMALLSTR)
|
||||
cp = malloc(j + 1, M_NFSSTRING, M_WAITOK);
|
||||
else
|
||||
@ -2371,7 +2434,7 @@ nfsv4_sattr(struct nfsrv_descript *nd, struct nfsvattr *nvap,
|
||||
if (error) {
|
||||
if (j > NFSV4_SMALLSTR)
|
||||
free(cp, M_NFSSTRING);
|
||||
return (error);
|
||||
goto nfsmout;
|
||||
}
|
||||
if (!nd->nd_repstat) {
|
||||
nd->nd_repstat = nfsv4_strtogid(cp,j,&gid,p);
|
||||
@ -2453,6 +2516,7 @@ nfsv4_sattr(struct nfsrv_descript *nd, struct nfsvattr *nvap,
|
||||
error = nfsm_advance(nd, attrsize - attrsum, -1);
|
||||
}
|
||||
nfsmout:
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -2484,14 +2548,16 @@ nfsd_excred(struct nfsrv_descript *nd, struct nfsexstuff *exp,
|
||||
error = NFSERR_WRONGSEC;
|
||||
else
|
||||
error = (NFSERR_AUTHERR | AUTH_TOOWEAK);
|
||||
return (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check to see if the file system is exported V4 only.
|
||||
*/
|
||||
if (NFSVNO_EXV4ONLY(exp) && !(nd->nd_flag & ND_NFSV4))
|
||||
return (NFSERR_PROGNOTV4);
|
||||
if (NFSVNO_EXV4ONLY(exp) && !(nd->nd_flag & ND_NFSV4)) {
|
||||
error = NFSERR_PROGNOTV4;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now, map the user credentials.
|
||||
@ -2508,7 +2574,10 @@ nfsd_excred(struct nfsrv_descript *nd, struct nfsexstuff *exp,
|
||||
crsetgroups(nd->nd_cred, credanon->cr_ngroups,
|
||||
credanon->cr_groups);
|
||||
}
|
||||
return (0);
|
||||
|
||||
out:
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2533,6 +2602,7 @@ nfsvno_checkexp(struct mount *mp, struct sockaddr *nam, struct nfsexstuff *exp,
|
||||
for (i = 0; i < exp->nes_numsecflavor; i++)
|
||||
exp->nes_secflavors[i] = secflavors[i];
|
||||
}
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -2579,6 +2649,8 @@ nfsvno_fhtovp(struct mount *mp, fhandle_t *fhp, struct sockaddr *nam,
|
||||
* type argument like VFS_VGET().
|
||||
*/
|
||||
NFSVOPLOCK(*vpp, LK_DOWNGRADE | LK_RETRY);
|
||||
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -2610,7 +2682,7 @@ nfsd_fhtovp(struct nfsrv_descript *nd, struct nfsrvfh *nfp, int lktype,
|
||||
if (mp == NULL) {
|
||||
*vpp = NULL;
|
||||
nd->nd_repstat = ESTALE;
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (startwrite)
|
||||
@ -2680,6 +2752,9 @@ nfsd_fhtovp(struct nfsrv_descript *nd, struct nfsrvfh *nfp, int lktype,
|
||||
if (mpp != NULL)
|
||||
*mpp = NULL;
|
||||
}
|
||||
|
||||
out:
|
||||
NFSEXITCODE2(0, nd);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2690,13 +2765,19 @@ fp_getfvp(struct thread *p, int fd, struct file **fpp, struct vnode **vpp)
|
||||
{
|
||||
struct filedesc *fdp;
|
||||
struct file *fp;
|
||||
int error = 0;
|
||||
|
||||
fdp = p->td_proc->p_fd;
|
||||
if (fd >= fdp->fd_nfiles ||
|
||||
(fp = fdp->fd_ofiles[fd]) == NULL)
|
||||
return (EBADF);
|
||||
(fp = fdp->fd_ofiles[fd]) == NULL) {
|
||||
error = EBADF;
|
||||
goto out;
|
||||
}
|
||||
*fpp = fp;
|
||||
return (0);
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2708,7 +2789,7 @@ int
|
||||
nfsrv_v4rootexport(void *argp, struct ucred *cred, struct thread *p)
|
||||
{
|
||||
struct nfsex_args *nfsexargp = (struct nfsex_args *)argp;
|
||||
int error;
|
||||
int error = 0;
|
||||
struct nameidata nd;
|
||||
fhandle_t fh;
|
||||
|
||||
@ -2716,15 +2797,17 @@ nfsrv_v4rootexport(void *argp, struct ucred *cred, struct thread *p)
|
||||
if ((nfsexargp->export.ex_flags & MNT_DELEXPORT) != 0)
|
||||
nfs_rootfhset = 0;
|
||||
else if (error == 0) {
|
||||
if (nfsexargp->fspec == NULL)
|
||||
return (EPERM);
|
||||
if (nfsexargp->fspec == NULL) {
|
||||
error = EPERM;
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* If fspec != NULL, this is the v4root path.
|
||||
*/
|
||||
NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_USERSPACE,
|
||||
nfsexargp->fspec, p);
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return (error);
|
||||
goto out;
|
||||
error = nfsvno_getfh(nd.ni_vp, &fh, p);
|
||||
vrele(nd.ni_vp);
|
||||
if (!error) {
|
||||
@ -2735,6 +2818,9 @@ nfsrv_v4rootexport(void *argp, struct ucred *cred, struct thread *p)
|
||||
nfs_rootfhset = 1;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -2747,23 +2833,29 @@ nfsrv_getsocksndseq(struct socket *so, tcp_seq *maxp, tcp_seq *unap)
|
||||
{
|
||||
struct inpcb *inp;
|
||||
struct tcpcb *tp;
|
||||
int error = 0;
|
||||
|
||||
inp = sotoinpcb(so);
|
||||
KASSERT(inp != NULL, ("nfsrv_getsocksndseq: inp == NULL"));
|
||||
INP_RLOCK(inp);
|
||||
if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
|
||||
INP_RUNLOCK(inp);
|
||||
return (EPIPE);
|
||||
error = EPIPE;
|
||||
goto out;
|
||||
}
|
||||
tp = intotcpcb(inp);
|
||||
if (tp->t_state != TCPS_ESTABLISHED) {
|
||||
INP_RUNLOCK(inp);
|
||||
return (EPIPE);
|
||||
error = EPIPE;
|
||||
goto out;
|
||||
}
|
||||
*maxp = tp->snd_max;
|
||||
*unap = tp->snd_una;
|
||||
INP_RUNLOCK(inp);
|
||||
return (0);
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2835,16 +2927,18 @@ int
|
||||
nfsvno_advlock(struct vnode *vp, int ftype, u_int64_t first,
|
||||
u_int64_t end, struct thread *td)
|
||||
{
|
||||
int error;
|
||||
int error = 0;
|
||||
struct flock fl;
|
||||
u_int64_t tlen;
|
||||
|
||||
if (nfsrv_dolocallocks == 0)
|
||||
return (0);
|
||||
goto out;
|
||||
|
||||
/* Check for VI_DOOMED here, so that VOP_ADVLOCK() isn't performed. */
|
||||
if ((vp->v_iflag & VI_DOOMED) != 0)
|
||||
return (EPERM);
|
||||
if ((vp->v_iflag & VI_DOOMED) != 0) {
|
||||
error = EPERM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
fl.l_whence = SEEK_SET;
|
||||
fl.l_type = ftype;
|
||||
@ -2876,6 +2970,9 @@ nfsvno_advlock(struct vnode *vp, int ftype, u_int64_t first,
|
||||
error = VOP_ADVLOCK(vp, (caddr_t)td->td_proc, F_SETLK, &fl,
|
||||
(F_POSIX | F_REMOTE));
|
||||
NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY);
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -2886,12 +2983,14 @@ int
|
||||
nfsvno_v4rootexport(struct nfsrv_descript *nd)
|
||||
{
|
||||
struct ucred *credanon;
|
||||
int exflags, error, numsecflavor, *secflavors, i;
|
||||
int exflags, error = 0, numsecflavor, *secflavors, i;
|
||||
|
||||
error = vfs_stdcheckexp(&nfsv4root_mnt, nd->nd_nam, &exflags,
|
||||
&credanon, &numsecflavor, &secflavors);
|
||||
if (error)
|
||||
return (NFSERR_PROGUNAVAIL);
|
||||
if (error) {
|
||||
error = NFSERR_PROGUNAVAIL;
|
||||
goto out;
|
||||
}
|
||||
if (credanon != NULL)
|
||||
crfree(credanon);
|
||||
for (i = 0; i < numsecflavor; i++) {
|
||||
@ -2904,7 +3003,10 @@ nfsvno_v4rootexport(struct nfsrv_descript *nd)
|
||||
else if (secflavors[i] == RPCSEC_GSS_KRB5P)
|
||||
nd->nd_flag |= ND_EXGSSPRIVACY;
|
||||
}
|
||||
return (0);
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2924,27 +3026,32 @@ nfssvc_nfsd(struct thread *td, struct nfssvc_args *uap)
|
||||
if (uap->flag & NFSSVC_NFSDADDSOCK) {
|
||||
error = copyin(uap->argp, (caddr_t)&sockarg, sizeof (sockarg));
|
||||
if (error)
|
||||
return (error);
|
||||
if ((error = fget(td, sockarg.sock, &fp)) != 0) {
|
||||
return (error);
|
||||
}
|
||||
goto out;
|
||||
if ((error = fget(td, sockarg.sock, &fp)) != 0)
|
||||
goto out;
|
||||
if (fp->f_type != DTYPE_SOCKET) {
|
||||
fdrop(fp, td);
|
||||
return (EPERM);
|
||||
error = EPERM;
|
||||
goto out;
|
||||
}
|
||||
error = nfsrvd_addsock(fp);
|
||||
fdrop(fp, td);
|
||||
} else if (uap->flag & NFSSVC_NFSDNFSD) {
|
||||
if (uap->argp == NULL)
|
||||
return (EINVAL);
|
||||
if (uap->argp == NULL) {
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
error = copyin(uap->argp, (caddr_t)&nfsdarg,
|
||||
sizeof (nfsdarg));
|
||||
if (error)
|
||||
return (error);
|
||||
goto out;
|
||||
error = nfsrvd_nfsd(td, &nfsdarg);
|
||||
} else {
|
||||
error = nfssvc_srvcall(td, uap, td->td_ucred);
|
||||
}
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -3042,6 +3149,8 @@ nfssvc_srvcall(struct thread *p, struct nfssvc_args *uap, struct ucred *cred)
|
||||
nfsd_master_proc = procp;
|
||||
PROC_UNLOCK(procp);
|
||||
}
|
||||
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -3136,7 +3245,7 @@ nfsd_modevent(module_t mod, int type, void *data)
|
||||
switch (type) {
|
||||
case MOD_LOAD:
|
||||
if (loaded)
|
||||
return (0);
|
||||
goto out;
|
||||
newnfs_portinit();
|
||||
mtx_init(&nfs_cache_mutex, "nfs_cache_mutex", NULL, MTX_DEF);
|
||||
mtx_init(&nfs_v4root_mutex, "nfs_v4root_mutex", NULL, MTX_DEF);
|
||||
@ -3192,7 +3301,10 @@ nfsd_modevent(module_t mod, int type, void *data)
|
||||
error = EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
return error;
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
static moduledata_t nfsd_mod = {
|
||||
"nfsd",
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -376,7 +376,7 @@ nfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram,
|
||||
if (error != EBADRPC)
|
||||
printf("nfs dorpc err1=%d\n", error);
|
||||
nd->nd_repstat = NFSERR_GARBAGE;
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
if (nd->nd_procnum == NFSPROC_READ ||
|
||||
nd->nd_procnum == NFSPROC_READDIR ||
|
||||
@ -393,7 +393,7 @@ nfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram,
|
||||
nfsd_fhtovp(nd, &fh, lktype, &vp, &nes,
|
||||
&mp, nfs_writerpc[nd->nd_procnum], p);
|
||||
if (nd->nd_repstat == NFSERR_PROGNOTV4)
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@ -416,7 +416,7 @@ nfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram,
|
||||
NFSINCRGLOBAL(newnfsstats.srvrpccnt[nfsv3to4op[nd->nd_procnum]]);
|
||||
if (mp != NULL && nfs_writerpc[nd->nd_procnum] != 0)
|
||||
vn_finished_write(mp);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -469,6 +469,9 @@ nfsrvd_dorpc(struct nfsrv_descript *nd, int isdgram,
|
||||
nd->nd_repstat == NFSERR_GRACE ||
|
||||
nd->nd_repstat == NFSERR_NOGRACE))
|
||||
nd->nd_flag &= ~ND_SAVEREPLY;
|
||||
|
||||
out:
|
||||
NFSEXITCODE2(0, nd);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -946,4 +949,6 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram,
|
||||
NFSLOCKV4ROOTMUTEX();
|
||||
nfsv4_relref(&nfsv4rootfs_lock);
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
|
||||
NFSEXITCODE2(0, nd);
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp,
|
||||
nfsquad_t *clientidp, nfsquad_t *confirmp, NFSPROC_T *p)
|
||||
{
|
||||
struct nfsclient *clp = NULL, *new_clp = *new_clpp;
|
||||
int i;
|
||||
int i, error = 0;
|
||||
struct nfsstate *stp, *tstp;
|
||||
struct sockaddr_in *sad, *rad;
|
||||
int zapit = 0, gotit, hasstate = 0, igotlock;
|
||||
@ -144,8 +144,10 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp,
|
||||
/*
|
||||
* Check for state resource limit exceeded.
|
||||
*/
|
||||
if (nfsrv_openpluslock > NFSRV_V4STATELIMIT)
|
||||
return (NFSERR_RESOURCE);
|
||||
if (nfsrv_openpluslock > NFSRV_V4STATELIMIT) {
|
||||
error = NFSERR_RESOURCE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nfsrv_issuedelegs == 0 ||
|
||||
((nd->nd_flag & ND_GSS) != 0 && nfsrv_nogsscallback != 0))
|
||||
@ -228,7 +230,7 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp,
|
||||
if (zapit)
|
||||
nfsrv_zapclient(clp, p);
|
||||
*new_clpp = NULL;
|
||||
return (0);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -274,7 +276,8 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp,
|
||||
NFSLOCKV4ROOTMUTEX();
|
||||
nfsv4_unlock(&nfsv4rootfs_lock, 1);
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
return (NFSERR_CLIDINUSE);
|
||||
error = NFSERR_CLIDINUSE;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@ -335,7 +338,7 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp,
|
||||
}
|
||||
nfsrv_zapclient(clp, p);
|
||||
*new_clpp = NULL;
|
||||
return (0);
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* id and verifier match, so update the net address info
|
||||
@ -388,7 +391,10 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp,
|
||||
}
|
||||
nfsrv_zapclient(clp, p);
|
||||
*new_clpp = NULL;
|
||||
return (0);
|
||||
|
||||
out:
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -406,8 +412,10 @@ nfsrv_getclient(nfsquad_t clientid, int opflags, struct nfsclient **clpp,
|
||||
|
||||
if (clpp)
|
||||
*clpp = NULL;
|
||||
if (nfsrvboottime != clientid.lval[0])
|
||||
return (NFSERR_STALECLIENTID);
|
||||
if (nfsrvboottime != clientid.lval[0]) {
|
||||
error = NFSERR_STALECLIENTID;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* If called with opflags == CLOPS_RENEW, the State Lock is
|
||||
@ -450,7 +458,7 @@ nfsrv_getclient(nfsquad_t clientid, int opflags, struct nfsclient **clpp,
|
||||
} else if (opflags != CLOPS_RENEW) {
|
||||
NFSUNLOCKSTATE();
|
||||
}
|
||||
return (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -526,6 +534,9 @@ nfsrv_getclient(nfsquad_t clientid, int opflags, struct nfsclient **clpp,
|
||||
}
|
||||
if (clpp)
|
||||
*clpp = clp;
|
||||
|
||||
out:
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -537,7 +548,7 @@ APPLESTATIC int
|
||||
nfsrv_adminrevoke(struct nfsd_clid *revokep, NFSPROC_T *p)
|
||||
{
|
||||
struct nfsclient *clp = NULL;
|
||||
int i;
|
||||
int i, error = 0;
|
||||
int gotit, igotlock;
|
||||
|
||||
/*
|
||||
@ -570,7 +581,8 @@ nfsrv_adminrevoke(struct nfsd_clid *revokep, NFSPROC_T *p)
|
||||
NFSLOCKV4ROOTMUTEX();
|
||||
nfsv4_unlock(&nfsv4rootfs_lock, 0);
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
return (EPERM);
|
||||
error = EPERM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -590,7 +602,10 @@ nfsrv_adminrevoke(struct nfsd_clid *revokep, NFSPROC_T *p)
|
||||
NFSLOCKV4ROOTMUTEX();
|
||||
nfsv4_unlock(&nfsv4rootfs_lock, 0);
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
return (0);
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1229,6 +1244,7 @@ nfsrv_getstate(struct nfsclient *clp, nfsv4stateid_t *stateidp, __unused u_int32
|
||||
{
|
||||
struct nfsstate *stp;
|
||||
struct nfsstatehead *hp;
|
||||
int error = 0;
|
||||
|
||||
*stpp = NULL;
|
||||
hp = NFSSTATEHASH(clp, *stateidp);
|
||||
@ -1241,10 +1257,15 @@ nfsrv_getstate(struct nfsclient *clp, nfsv4stateid_t *stateidp, __unused u_int32
|
||||
/*
|
||||
* If no state id in list, return NFSERR_BADSTATEID.
|
||||
*/
|
||||
if (stp == LIST_END(hp))
|
||||
return (NFSERR_BADSTATEID);
|
||||
if (stp == LIST_END(hp)) {
|
||||
error = NFSERR_BADSTATEID;
|
||||
goto out;
|
||||
}
|
||||
*stpp = stp;
|
||||
return (0);
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1323,14 +1344,16 @@ nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp,
|
||||
error = nfsrv_checkrestart(clientid, new_stp->ls_flags,
|
||||
&new_stp->ls_stateid, specialid);
|
||||
if (error)
|
||||
return (error);
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Check for state resource limit exceeded.
|
||||
*/
|
||||
if ((new_stp->ls_flags & NFSLCK_LOCK) &&
|
||||
nfsrv_openpluslock > NFSRV_V4STATELIMIT)
|
||||
return (NFSERR_RESOURCE);
|
||||
nfsrv_openpluslock > NFSRV_V4STATELIMIT) {
|
||||
error = NFSERR_RESOURCE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* For the lock case, get another nfslock structure,
|
||||
@ -1546,14 +1569,7 @@ nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp,
|
||||
nfsrv_unlocklf(lfp);
|
||||
}
|
||||
NFSUNLOCKSTATE();
|
||||
if (other_lop)
|
||||
FREE((caddr_t)other_lop, M_NFSDLOCK);
|
||||
if (haslock) {
|
||||
NFSLOCKV4ROOTMUTEX();
|
||||
nfsv4_unlock(&nfsv4rootfs_lock, 1);
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
}
|
||||
return (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1582,15 +1598,7 @@ nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp,
|
||||
error = NFSERR_BADSTATEID;
|
||||
}
|
||||
NFSUNLOCKSTATE();
|
||||
if (haslock) {
|
||||
NFSLOCKV4ROOTMUTEX();
|
||||
nfsv4_unlock(&nfsv4rootfs_lock, 1);
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
}
|
||||
/*
|
||||
* Called to lock or unlock, so the lock has gone away.
|
||||
*/
|
||||
return (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1638,14 +1646,8 @@ nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp,
|
||||
nfsrv_unlocklf(lfp);
|
||||
}
|
||||
NFSUNLOCKSTATE();
|
||||
if (other_lop)
|
||||
FREE((caddr_t)other_lop, M_NFSDLOCK);
|
||||
if (haslock) {
|
||||
NFSLOCKV4ROOTMUTEX();
|
||||
nfsv4_unlock(&nfsv4rootfs_lock, 1);
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
}
|
||||
return (NFSERR_OPENMODE);
|
||||
error = NFSERR_OPENMODE;
|
||||
goto out;
|
||||
}
|
||||
} else
|
||||
mystp = NULL;
|
||||
@ -1670,27 +1672,18 @@ nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp,
|
||||
}
|
||||
if (ret == 0)
|
||||
NFSUNLOCKSTATE();
|
||||
if (haslock) {
|
||||
NFSLOCKV4ROOTMUTEX();
|
||||
nfsv4_unlock(&nfsv4rootfs_lock, 1);
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
}
|
||||
if (ret == 2)
|
||||
return (NFSERR_PERM);
|
||||
error = NFSERR_PERM;
|
||||
else
|
||||
return (NFSERR_OPENMODE);
|
||||
error = NFSERR_OPENMODE;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We're outta here */
|
||||
NFSUNLOCKSTATE();
|
||||
if (haslock) {
|
||||
NFSLOCKV4ROOTMUTEX();
|
||||
nfsv4_unlock(&nfsv4rootfs_lock, 1);
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
}
|
||||
return (0);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1708,18 +1701,14 @@ nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp,
|
||||
lckstp = NULL;
|
||||
goto tryagain;
|
||||
}
|
||||
return (ret);
|
||||
error = ret;
|
||||
goto out;
|
||||
}
|
||||
if (!(new_stp->ls_flags & NFSLCK_CHECK) ||
|
||||
(LIST_EMPTY(&lfp->lf_open) && LIST_EMPTY(&lfp->lf_lock) &&
|
||||
LIST_EMPTY(&lfp->lf_deleg))) {
|
||||
NFSUNLOCKSTATE();
|
||||
if (haslock) {
|
||||
NFSLOCKV4ROOTMUTEX();
|
||||
nfsv4_unlock(&nfsv4rootfs_lock, 1);
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
}
|
||||
return (0);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1773,7 +1762,8 @@ nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp,
|
||||
lckstp = NULL;
|
||||
goto tryagain;
|
||||
}
|
||||
return (ret);
|
||||
error = ret;
|
||||
goto out;
|
||||
}
|
||||
/* Never gets here. */
|
||||
}
|
||||
@ -1801,12 +1791,7 @@ nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp,
|
||||
nfsrv_unlocklf(lfp);
|
||||
}
|
||||
NFSUNLOCKSTATE();
|
||||
if (haslock) {
|
||||
NFSLOCKV4ROOTMUTEX();
|
||||
nfsv4_unlock(&nfsv4rootfs_lock, 1);
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
}
|
||||
return (0);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1877,12 +1862,7 @@ nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp,
|
||||
}
|
||||
if (ret == 0)
|
||||
NFSUNLOCKSTATE();
|
||||
if (haslock) {
|
||||
NFSLOCKV4ROOTMUTEX();
|
||||
nfsv4_unlock(&nfsv4rootfs_lock, 1);
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
}
|
||||
return (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1892,12 +1872,7 @@ nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp,
|
||||
*/
|
||||
if (new_stp->ls_flags & (NFSLCK_TEST | NFSLCK_CHECK)) {
|
||||
NFSUNLOCKSTATE();
|
||||
if (haslock) {
|
||||
NFSLOCKV4ROOTMUTEX();
|
||||
nfsv4_unlock(&nfsv4rootfs_lock, 1);
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
}
|
||||
return (0);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1950,6 +1925,8 @@ nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp,
|
||||
nfsrv_unlocklf(lfp);
|
||||
}
|
||||
NFSUNLOCKSTATE();
|
||||
|
||||
out:
|
||||
if (haslock) {
|
||||
NFSLOCKV4ROOTMUTEX();
|
||||
nfsv4_unlock(&nfsv4rootfs_lock, 1);
|
||||
@ -1957,7 +1934,8 @@ nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp,
|
||||
}
|
||||
if (other_lop)
|
||||
FREE((caddr_t)other_lop, M_NFSDLOCK);
|
||||
return (0);
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1974,7 +1952,7 @@ nfsrv_opencheck(nfsquad_t clientid, nfsv4stateid_t *stateidp,
|
||||
struct nfsclient *clp;
|
||||
struct nfsstate *ownerstp;
|
||||
struct nfslockfile *lfp, *new_lfp;
|
||||
int error, haslock = 0, ret, readonly = 0, getfhret = 0;
|
||||
int error = 0, haslock = 0, ret, readonly = 0, getfhret = 0;
|
||||
|
||||
if ((new_stp->ls_flags & NFSLCK_SHAREBITS) == NFSLCK_READACCESS)
|
||||
readonly = 1;
|
||||
@ -1984,7 +1962,7 @@ nfsrv_opencheck(nfsquad_t clientid, nfsv4stateid_t *stateidp,
|
||||
error = nfsrv_checkrestart(clientid, new_stp->ls_flags,
|
||||
&new_stp->ls_stateid, 0);
|
||||
if (error)
|
||||
return (error);
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Check for state resource limit exceeded.
|
||||
@ -1993,8 +1971,10 @@ nfsrv_opencheck(nfsquad_t clientid, nfsv4stateid_t *stateidp,
|
||||
* returns NFSERR_RESOURCE and the limit is just a rather
|
||||
* arbitrary high water mark, so no harm is done.
|
||||
*/
|
||||
if (nfsrv_openpluslock > NFSRV_V4STATELIMIT)
|
||||
return (NFSERR_RESOURCE);
|
||||
if (nfsrv_openpluslock > NFSRV_V4STATELIMIT) {
|
||||
error = NFSERR_RESOURCE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
tryagain:
|
||||
MALLOC(new_lfp, struct nfslockfile *, sizeof (struct nfslockfile),
|
||||
@ -2052,7 +2032,7 @@ nfsrv_opencheck(nfsquad_t clientid, nfsv4stateid_t *stateidp,
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
}
|
||||
free((caddr_t)new_lfp, M_NFSDLOCKFILE);
|
||||
return (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2062,7 +2042,7 @@ nfsrv_opencheck(nfsquad_t clientid, nfsv4stateid_t *stateidp,
|
||||
if (vp == NULL) {
|
||||
NFSUNLOCKSTATE();
|
||||
FREE((caddr_t)new_lfp, M_NFSDLOCKFILE);
|
||||
return (0);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2082,7 +2062,7 @@ nfsrv_opencheck(nfsquad_t clientid, nfsv4stateid_t *stateidp,
|
||||
nfsv4_unlock(&nfsv4rootfs_lock, 1);
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
}
|
||||
return (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2113,7 +2093,8 @@ nfsrv_opencheck(nfsquad_t clientid, nfsv4stateid_t *stateidp,
|
||||
nfsv4_unlock(&nfsv4rootfs_lock, 1);
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
}
|
||||
return (NFSERR_EXPIRED);
|
||||
error = NFSERR_EXPIRED;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2148,7 +2129,7 @@ nfsrv_opencheck(nfsquad_t clientid, nfsv4stateid_t *stateidp,
|
||||
nfsv4_unlock(&nfsv4rootfs_lock, 1);
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
}
|
||||
return (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2189,7 +2170,8 @@ nfsrv_opencheck(nfsquad_t clientid, nfsv4stateid_t *stateidp,
|
||||
*/
|
||||
if (ret == -1)
|
||||
goto tryagain;
|
||||
return (ret);
|
||||
error = ret;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
stp = nstp;
|
||||
@ -2201,7 +2183,10 @@ nfsrv_opencheck(nfsquad_t clientid, nfsv4stateid_t *stateidp,
|
||||
nfsv4_unlock(&nfsv4rootfs_lock, 1);
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
}
|
||||
return (0);
|
||||
|
||||
out:
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2218,7 +2203,7 @@ nfsrv_openctrl(struct nfsrv_descript *nd, vnode_t vp,
|
||||
struct nfsstate *openstp = NULL, *new_open, *ownerstp, *new_deleg;
|
||||
struct nfslockfile *lfp, *new_lfp;
|
||||
struct nfsclient *clp;
|
||||
int error, haslock = 0, ret, delegate = 1, writedeleg = 1;
|
||||
int error = 0, haslock = 0, ret, delegate = 1, writedeleg = 1;
|
||||
int readonly = 0, cbret = 1, getfhret = 0;
|
||||
|
||||
if ((new_stp->ls_flags & NFSLCK_SHAREBITS) == NFSLCK_READACCESS)
|
||||
@ -2234,7 +2219,8 @@ nfsrv_openctrl(struct nfsrv_descript *nd, vnode_t vp,
|
||||
if (error) {
|
||||
printf("Nfsd: openctrl unexpected restart err=%d\n",
|
||||
error);
|
||||
return (NFSERR_EXPIRED);
|
||||
error = NFSERR_EXPIRED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
tryagain:
|
||||
@ -2305,7 +2291,8 @@ nfsrv_openctrl(struct nfsrv_descript *nd, vnode_t vp,
|
||||
nfsv4_unlock(&nfsv4rootfs_lock, 1);
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
}
|
||||
return (NFSERR_EXPIRED);
|
||||
error = NFSERR_EXPIRED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (new_stp->ls_flags & NFSLCK_RECLAIM)
|
||||
@ -2332,7 +2319,7 @@ nfsrv_openctrl(struct nfsrv_descript *nd, vnode_t vp,
|
||||
nfsv4_unlock(&nfsv4rootfs_lock, 1);
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
}
|
||||
return (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2366,7 +2353,8 @@ nfsrv_openctrl(struct nfsrv_descript *nd, vnode_t vp,
|
||||
nfsv4_unlock(&nfsv4rootfs_lock, 1);
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
}
|
||||
return (NFSERR_EXPIRED);
|
||||
error = NFSERR_EXPIRED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2431,7 +2419,7 @@ nfsrv_openctrl(struct nfsrv_descript *nd, vnode_t vp,
|
||||
free((caddr_t)new_open, M_NFSDSTATE);
|
||||
free((caddr_t)new_deleg, M_NFSDSTATE);
|
||||
printf("nfsd openctrl unexpected client cnfl\n");
|
||||
return (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2482,7 +2470,8 @@ nfsrv_openctrl(struct nfsrv_descript *nd, vnode_t vp,
|
||||
openstp = NULL;
|
||||
goto tryagain;
|
||||
}
|
||||
return (ret);
|
||||
error = ret;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2855,6 +2844,9 @@ nfsrv_openctrl(struct nfsrv_descript *nd, vnode_t vp,
|
||||
FREE((caddr_t)new_open, M_NFSDSTATE);
|
||||
if (new_deleg)
|
||||
FREE((caddr_t)new_deleg, M_NFSDSTATE);
|
||||
|
||||
out:
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -2869,7 +2861,7 @@ nfsrv_openupdate(vnode_t vp, struct nfsstate *new_stp, nfsquad_t clientid,
|
||||
struct nfsclient *clp;
|
||||
struct nfslockfile *lfp;
|
||||
u_int32_t bits;
|
||||
int error, gotstate = 0, len = 0;
|
||||
int error = 0, gotstate = 0, len = 0;
|
||||
u_char client[NFSV4_OPAQUELIMIT];
|
||||
|
||||
/*
|
||||
@ -2878,7 +2870,7 @@ nfsrv_openupdate(vnode_t vp, struct nfsstate *new_stp, nfsquad_t clientid,
|
||||
error = nfsrv_checkrestart(clientid, new_stp->ls_flags,
|
||||
&new_stp->ls_stateid, 0);
|
||||
if (error)
|
||||
return (error);
|
||||
goto out;
|
||||
|
||||
NFSLOCKSTATE();
|
||||
/*
|
||||
@ -2925,7 +2917,7 @@ nfsrv_openupdate(vnode_t vp, struct nfsstate *new_stp, nfsquad_t clientid,
|
||||
nfsrv_nootherstate(stp))
|
||||
nfsrv_freeopenowner(stp->ls_openowner, 0, p);
|
||||
NFSUNLOCKSTATE();
|
||||
return (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2978,7 +2970,8 @@ nfsrv_openupdate(vnode_t vp, struct nfsstate *new_stp, nfsquad_t clientid,
|
||||
bits = (new_stp->ls_flags & NFSLCK_SHAREBITS);
|
||||
if (~(stp->ls_flags) & bits) {
|
||||
NFSUNLOCKSTATE();
|
||||
return (NFSERR_INVAL);
|
||||
error = NFSERR_INVAL;
|
||||
goto out;
|
||||
}
|
||||
stp->ls_flags = (bits | NFSLCK_OPEN);
|
||||
stp->ls_stateid.seqid++;
|
||||
@ -2993,6 +2986,9 @@ nfsrv_openupdate(vnode_t vp, struct nfsstate *new_stp, nfsquad_t clientid,
|
||||
nfsrv_writestable(client, len, NFSNST_NEWSTATE, p);
|
||||
nfsrv_backupstable();
|
||||
}
|
||||
|
||||
out:
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -3005,7 +3001,7 @@ nfsrv_delegupdate(nfsquad_t clientid, nfsv4stateid_t *stateidp,
|
||||
{
|
||||
struct nfsstate *stp;
|
||||
struct nfsclient *clp;
|
||||
int error;
|
||||
int error = 0;
|
||||
fhandle_t fh;
|
||||
|
||||
/*
|
||||
@ -3014,7 +3010,7 @@ nfsrv_delegupdate(nfsquad_t clientid, nfsv4stateid_t *stateidp,
|
||||
if (vp) {
|
||||
error = nfsvno_getfh(vp, &fh, p);
|
||||
if (error)
|
||||
return (error);
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* Check for restart conditions (client and server).
|
||||
@ -3050,25 +3046,31 @@ nfsrv_delegupdate(nfsquad_t clientid, nfsv4stateid_t *stateidp,
|
||||
*/
|
||||
if (error == NFSERR_EXPIRED && op == NFSV4OP_DELEGPURGE) {
|
||||
NFSUNLOCKSTATE();
|
||||
return (0);
|
||||
error = 0;
|
||||
goto out;
|
||||
}
|
||||
if (error) {
|
||||
NFSUNLOCKSTATE();
|
||||
return (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (op == NFSV4OP_DELEGRETURN) {
|
||||
if (NFSBCMP((caddr_t)&fh, (caddr_t)&stp->ls_lfp->lf_fh,
|
||||
sizeof (fhandle_t))) {
|
||||
NFSUNLOCKSTATE();
|
||||
return (NFSERR_BADSTATEID);
|
||||
error = NFSERR_BADSTATEID;
|
||||
goto out;
|
||||
}
|
||||
nfsrv_freedeleg(stp);
|
||||
} else {
|
||||
nfsrv_freedeleglist(&clp->lc_olddeleg);
|
||||
}
|
||||
NFSUNLOCKSTATE();
|
||||
return (0);
|
||||
error = 0;
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3080,7 +3082,7 @@ nfsrv_releaselckown(struct nfsstate *new_stp, nfsquad_t clientid,
|
||||
{
|
||||
struct nfsstate *stp, *nstp, *openstp, *ownstp;
|
||||
struct nfsclient *clp;
|
||||
int error;
|
||||
int error = 0;
|
||||
|
||||
/*
|
||||
* Check for restart conditions (client and server).
|
||||
@ -3088,7 +3090,7 @@ nfsrv_releaselckown(struct nfsstate *new_stp, nfsquad_t clientid,
|
||||
error = nfsrv_checkrestart(clientid, new_stp->ls_flags,
|
||||
&new_stp->ls_stateid, 0);
|
||||
if (error)
|
||||
return (error);
|
||||
goto out;
|
||||
|
||||
NFSLOCKSTATE();
|
||||
/*
|
||||
@ -3098,7 +3100,7 @@ nfsrv_releaselckown(struct nfsstate *new_stp, nfsquad_t clientid,
|
||||
(nfsquad_t)((u_quad_t)0), NULL, p);
|
||||
if (error) {
|
||||
NFSUNLOCKSTATE();
|
||||
return (error);
|
||||
goto out;
|
||||
}
|
||||
LIST_FOREACH(ownstp, &clp->lc_open, ls_list) {
|
||||
LIST_FOREACH(openstp, &ownstp->ls_open, ls_list) {
|
||||
@ -3116,7 +3118,8 @@ nfsrv_releaselckown(struct nfsstate *new_stp, nfsquad_t clientid,
|
||||
nfsrv_freelockowner(stp, NULL, 0, p);
|
||||
} else {
|
||||
NFSUNLOCKSTATE();
|
||||
return (NFSERR_LOCKSHELD);
|
||||
error = NFSERR_LOCKSHELD;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
stp = nstp;
|
||||
@ -3124,7 +3127,10 @@ nfsrv_releaselckown(struct nfsstate *new_stp, nfsquad_t clientid,
|
||||
}
|
||||
}
|
||||
NFSUNLOCKSTATE();
|
||||
return (0);
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3151,6 +3157,7 @@ nfsrv_getlockfh(vnode_t vp, u_short flags,
|
||||
panic("nfsrv_getlockfh");
|
||||
}
|
||||
error = nfsvno_getfh(vp, fhp, p);
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -3406,6 +3413,7 @@ static int
|
||||
nfsrv_checkseqid(struct nfsrv_descript *nd, u_int32_t seqid,
|
||||
struct nfsstate *stp, struct nfsrvcache *op)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
if (op != nd->nd_rp)
|
||||
panic("nfsrvstate checkseqid");
|
||||
@ -3421,20 +3429,27 @@ nfsrv_checkseqid(struct nfsrv_descript *nd, u_int32_t seqid,
|
||||
stp->ls_op = op;
|
||||
nfsrvd_refcache(op);
|
||||
stp->ls_seq = seqid;
|
||||
return (0);
|
||||
goto out;
|
||||
} else if (stp->ls_seq == seqid && stp->ls_op &&
|
||||
op->rc_xid == stp->ls_op->rc_xid &&
|
||||
op->rc_refcnt == 0 &&
|
||||
op->rc_reqlen == stp->ls_op->rc_reqlen &&
|
||||
op->rc_cksum == stp->ls_op->rc_cksum) {
|
||||
if (stp->ls_op->rc_flag & RC_INPROG)
|
||||
return (NFSERR_DONTREPLY);
|
||||
if (stp->ls_op->rc_flag & RC_INPROG) {
|
||||
error = NFSERR_DONTREPLY;
|
||||
goto out;
|
||||
}
|
||||
nd->nd_rp = stp->ls_op;
|
||||
nd->nd_rp->rc_flag |= RC_INPROG;
|
||||
nfsrvd_delcache(op);
|
||||
return (NFSERR_REPLYFROMCACHE);
|
||||
error = NFSERR_REPLYFROMCACHE;
|
||||
goto out;
|
||||
}
|
||||
return (NFSERR_BADSEQID);
|
||||
error = NFSERR_BADSEQID;
|
||||
|
||||
out:
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3558,6 +3573,7 @@ nfsrv_getclientipaddr(struct nfsrv_descript *nd, struct nfsclient *clp)
|
||||
clp->lc_program = 0;
|
||||
}
|
||||
nfsmout:
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -3590,7 +3606,7 @@ static int
|
||||
nfsrv_checkrestart(nfsquad_t clientid, u_int32_t flags,
|
||||
nfsv4stateid_t *stateidp, int specialid)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* First check for a server restart. Open, LockT, ReleaseLockOwner
|
||||
@ -3598,11 +3614,15 @@ nfsrv_checkrestart(nfsquad_t clientid, u_int32_t flags,
|
||||
*/
|
||||
if (flags &
|
||||
(NFSLCK_OPEN | NFSLCK_TEST | NFSLCK_RELEASE | NFSLCK_DELEGPURGE)) {
|
||||
if (clientid.lval[0] != nfsrvboottime)
|
||||
return (NFSERR_STALECLIENTID);
|
||||
if (clientid.lval[0] != nfsrvboottime) {
|
||||
ret = NFSERR_STALECLIENTID;
|
||||
goto out;
|
||||
}
|
||||
} else if (stateidp->other[0] != nfsrvboottime &&
|
||||
specialid == 0)
|
||||
return (NFSERR_STALESTATEID);
|
||||
specialid == 0) {
|
||||
ret = NFSERR_STALESTATEID;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read, Write, Setattr and LockT can return NFSERR_GRACE and do
|
||||
@ -3610,11 +3630,14 @@ nfsrv_checkrestart(nfsquad_t clientid, u_int32_t flags,
|
||||
* (The others will be checked, as required, later.)
|
||||
*/
|
||||
if (!(flags & (NFSLCK_CHECK | NFSLCK_TEST)))
|
||||
return (0);
|
||||
goto out;
|
||||
|
||||
NFSLOCKSTATE();
|
||||
ret = nfsrv_checkgrace(flags);
|
||||
NFSUNLOCKSTATE();
|
||||
|
||||
out:
|
||||
NFSEXITCODE(ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -3624,13 +3647,18 @@ nfsrv_checkrestart(nfsquad_t clientid, u_int32_t flags,
|
||||
static int
|
||||
nfsrv_checkgrace(u_int32_t flags)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
if (nfsrv_stablefirst.nsf_flags & NFSNSF_GRACEOVER) {
|
||||
if (flags & NFSLCK_RECLAIM)
|
||||
return (NFSERR_NOGRACE);
|
||||
if (flags & NFSLCK_RECLAIM) {
|
||||
error = NFSERR_NOGRACE;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
if (!(flags & NFSLCK_RECLAIM))
|
||||
return (NFSERR_GRACE);
|
||||
if (!(flags & NFSLCK_RECLAIM)) {
|
||||
error = NFSERR_GRACE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* If grace is almost over and we are still getting Reclaims,
|
||||
@ -3641,7 +3669,10 @@ nfsrv_checkgrace(u_int32_t flags)
|
||||
nfsrv_stablefirst.nsf_eograce = NFSD_MONOSEC +
|
||||
NFSRV_LEASEDELTA;
|
||||
}
|
||||
return (0);
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3790,6 +3821,8 @@ nfsrv_docallback(struct nfsclient *clp, int procnum,
|
||||
} else {
|
||||
NFSUNLOCKSTATE();
|
||||
}
|
||||
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -4317,7 +4350,8 @@ nfsrv_delegconflict(struct nfsstate *stp, int *haslockp, NFSPROC_T *p,
|
||||
if (clp->lc_delegtime < NFSD_MONOSEC) {
|
||||
nfsrv_freedeleg(stp);
|
||||
NFSUNLOCKSTATE();
|
||||
return (-1);
|
||||
error = -1;
|
||||
goto out;
|
||||
}
|
||||
NFSUNLOCKSTATE();
|
||||
/*
|
||||
@ -4332,7 +4366,8 @@ nfsrv_delegconflict(struct nfsstate *stp, int *haslockp, NFSPROC_T *p,
|
||||
nfsv4_unlock(&nfsv4rootfs_lock, 1);
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
}
|
||||
return (NFSERR_DELAY);
|
||||
error = NFSERR_DELAY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4388,7 +4423,8 @@ nfsrv_delegconflict(struct nfsstate *stp, int *haslockp, NFSPROC_T *p,
|
||||
retrycnt++;
|
||||
} while ((error == NFSERR_BADSTATEID ||
|
||||
error == NFSERR_BADHANDLE) && retrycnt < NFSV4_CBRETRYCNT);
|
||||
return (NFSERR_DELAY);
|
||||
error = NFSERR_DELAY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (clp->lc_expiry >= NFSD_MONOSEC &&
|
||||
@ -4404,7 +4440,8 @@ nfsrv_delegconflict(struct nfsstate *stp, int *haslockp, NFSPROC_T *p,
|
||||
nfsv4_unlock(&nfsv4rootfs_lock, 1);
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
}
|
||||
return (NFSERR_DELAY);
|
||||
error = NFSERR_DELAY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4432,9 +4469,11 @@ nfsrv_delegconflict(struct nfsstate *stp, int *haslockp, NFSPROC_T *p,
|
||||
NFSLOCKV4ROOTMUTEX();
|
||||
nfsv4_unlock(&nfsv4rootfs_lock, 1);
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
return (NFSERR_PERM);
|
||||
error = NFSERR_PERM;
|
||||
goto out;
|
||||
}
|
||||
return (-1);
|
||||
error = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
NFSUNLOCKSTATE();
|
||||
@ -4459,7 +4498,11 @@ nfsrv_delegconflict(struct nfsstate *stp, int *haslockp, NFSPROC_T *p,
|
||||
}
|
||||
if (zapped_clp)
|
||||
nfsrv_zapclient(clp, p);
|
||||
return (-1);
|
||||
error = -1;
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4491,8 +4534,8 @@ nfsrv_checkremove(vnode_t vp, int remove, NFSPROC_T *p)
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
}
|
||||
if (error == -1)
|
||||
return (0);
|
||||
return (error);
|
||||
error = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4511,7 +4554,7 @@ nfsrv_checkremove(vnode_t vp, int remove, NFSPROC_T *p)
|
||||
nfsv4_unlock(&nfsv4rootfs_lock, 1);
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
}
|
||||
return (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4532,6 +4575,9 @@ nfsrv_checkremove(vnode_t vp, int remove, NFSPROC_T *p)
|
||||
nfsv4_unlock(&nfsv4rootfs_lock, 1);
|
||||
NFSUNLOCKV4ROOTMUTEX();
|
||||
}
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -4549,7 +4595,7 @@ nfsrv_cleandeleg(vnode_t vp, struct nfslockfile *lfp,
|
||||
struct nfsclient *clp, int *haslockp, NFSPROC_T *p)
|
||||
{
|
||||
struct nfsstate *stp, *nstp;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
stp = LIST_FIRST(&lfp->lf_deleg);
|
||||
while (stp != LIST_END(&lfp->lf_deleg)) {
|
||||
@ -4561,12 +4607,14 @@ nfsrv_cleandeleg(vnode_t vp, struct nfslockfile *lfp,
|
||||
* nfsrv_delegconflict() unlocks state
|
||||
* when it returns non-zero.
|
||||
*/
|
||||
return (ret);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
stp = nstp;
|
||||
}
|
||||
return (0);
|
||||
out:
|
||||
NFSEXITCODE(ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4700,7 +4748,7 @@ nfsrv_checksetattr(vnode_t vp, struct nfsrv_descript *nd,
|
||||
NFSISSET_ATTRBIT(attrbitp, NFSATTRBIT_ACL))
|
||||
stp->ls_flags |= NFSLCK_SETATTR;
|
||||
if (stp->ls_flags == 0)
|
||||
return (0);
|
||||
goto out;
|
||||
lop->lo_end = NFS64BITSSET;
|
||||
lop->lo_flags = NFSLCK_WRITE;
|
||||
stp->ls_ownerlen = 0;
|
||||
@ -4712,6 +4760,9 @@ nfsrv_checksetattr(vnode_t vp, struct nfsrv_descript *nd,
|
||||
stp->ls_stateid.other[2] = stateidp->other[2];
|
||||
error = nfsrv_lockctrl(vp, &stp, &lop, NULL, clientid,
|
||||
stateidp, exp, nd, p);
|
||||
|
||||
out:
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -4731,13 +4782,13 @@ nfsrv_checkgetattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
struct nfsclient *clp;
|
||||
struct nfsvattr nva;
|
||||
fhandle_t nfh;
|
||||
int error;
|
||||
int error = 0;
|
||||
nfsattrbit_t cbbits;
|
||||
u_quad_t delegfilerev;
|
||||
|
||||
NFSCBGETATTR_ATTRBIT(attrbitp, &cbbits);
|
||||
if (!NFSNONZERO_ATTRBIT(&cbbits))
|
||||
return (0);
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Get the lock file structure.
|
||||
@ -4750,8 +4801,8 @@ nfsrv_checkgetattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
if (error) {
|
||||
NFSUNLOCKSTATE();
|
||||
if (error == -1)
|
||||
return (0);
|
||||
return (error);
|
||||
error = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4763,7 +4814,7 @@ nfsrv_checkgetattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
}
|
||||
if (stp == LIST_END(&lfp->lf_deleg)) {
|
||||
NFSUNLOCKSTATE();
|
||||
return (0);
|
||||
goto out;
|
||||
}
|
||||
clp = stp->ls_clp;
|
||||
delegfilerev = stp->ls_filerev;
|
||||
@ -4783,7 +4834,7 @@ nfsrv_checkgetattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
clp->lc_clientid.qval == nd->nd_clientid.qval) ||
|
||||
nfsaddr2_match(clp->lc_req.nr_nam, nd->nd_nam)) {
|
||||
NFSUNLOCKSTATE();
|
||||
return (0);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4814,7 +4865,11 @@ nfsrv_checkgetattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
} else {
|
||||
NFSUNLOCKSTATE();
|
||||
}
|
||||
return (0);
|
||||
error = 0;
|
||||
|
||||
out:
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4997,6 +5052,8 @@ nfsrv_locallock(vnode_t vp, struct nfslockfile *lfp, int flags,
|
||||
/* handle fragment past end of list */
|
||||
error = nfsrv_dolocal(vp, lfp, flags, NFSLCK_UNLOCK, first,
|
||||
end, cfp, p);
|
||||
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -5079,7 +5136,7 @@ nfsrv_dolocal(vnode_t vp, struct nfslockfile *lfp, int flags, int oldflags,
|
||||
uint64_t first, uint64_t end, struct nfslockconflict *cfp, NFSPROC_T *p)
|
||||
{
|
||||
struct nfsrollback *rlp;
|
||||
int error, ltype, oldltype;
|
||||
int error = 0, ltype, oldltype;
|
||||
|
||||
if (flags & NFSLCK_WRITE)
|
||||
ltype = F_WRLCK;
|
||||
@ -5095,7 +5152,7 @@ nfsrv_dolocal(vnode_t vp, struct nfslockfile *lfp, int flags, int oldflags,
|
||||
oldltype = F_UNLCK;
|
||||
if (ltype == oldltype || (oldltype == F_WRLCK && ltype == F_RDLCK))
|
||||
/* nothing to do */
|
||||
return (0);
|
||||
goto out;
|
||||
error = nfsvno_advlock(vp, ltype, first, end, p);
|
||||
if (error != 0) {
|
||||
if (cfp != NULL) {
|
||||
@ -5116,6 +5173,9 @@ nfsrv_dolocal(vnode_t vp, struct nfslockfile *lfp, int flags, int oldflags,
|
||||
rlp->rlck_type = oldltype;
|
||||
LIST_INSERT_HEAD(&lfp->lf_rollback, rlp, rlck_list);
|
||||
}
|
||||
|
||||
out:
|
||||
NFSEXITCODE(error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -1418,21 +1418,23 @@ nfsrv_mtofh(struct nfsrv_descript *nd, struct nfsrvfh *fhp)
|
||||
if (len == 0 && nfs_pubfhset && (nd->nd_flag & ND_NFSV3) &&
|
||||
nd->nd_procnum == NFSPROC_LOOKUP) {
|
||||
nd->nd_flag |= ND_PUBLOOKUP;
|
||||
return (0);
|
||||
goto nfsmout;
|
||||
}
|
||||
if (len < NFSRV_MINFH || len > NFSRV_MAXFH) {
|
||||
if (nd->nd_flag & ND_NFSV4) {
|
||||
if (len > 0 && len <= NFSX_V4FHMAX) {
|
||||
error = nfsm_advance(nd, NFSM_RNDUP(len), -1);
|
||||
if (error)
|
||||
return (error);
|
||||
goto nfsmout;
|
||||
nd->nd_repstat = NFSERR_BADHANDLE;
|
||||
return (0);
|
||||
goto nfsmout;
|
||||
} else {
|
||||
return (EBADRPC);
|
||||
error = EBADRPC;
|
||||
goto nfsmout;
|
||||
}
|
||||
} else {
|
||||
return (EBADRPC);
|
||||
error = EBADRPC;
|
||||
goto nfsmout;
|
||||
}
|
||||
}
|
||||
copylen = len;
|
||||
@ -1450,11 +1452,12 @@ nfsrv_mtofh(struct nfsrv_descript *nd, struct nfsrvfh *fhp)
|
||||
nd->nd_procnum == NFSPROC_LOOKUP &&
|
||||
!NFSBCMP((caddr_t)tl, nfs_v2pubfh, NFSX_V2FH)) {
|
||||
nd->nd_flag |= ND_PUBLOOKUP;
|
||||
return (0);
|
||||
goto nfsmout;
|
||||
}
|
||||
NFSBCOPY(tl, (caddr_t)fhp->nfsrvfh_data, copylen);
|
||||
fhp->nfsrvfh_len = copylen;
|
||||
nfsmout:
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -1503,22 +1506,28 @@ nfsd_errmap(struct nfsrv_descript *nd)
|
||||
APPLESTATIC int
|
||||
nfsrv_checkuidgid(struct nfsrv_descript *nd, struct nfsvattr *nvap)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
/*
|
||||
* If not setting either uid nor gid, it's OK.
|
||||
*/
|
||||
if (NFSVNO_NOTSETUID(nvap) && NFSVNO_NOTSETGID(nvap))
|
||||
return (0);
|
||||
goto out;
|
||||
if ((NFSVNO_ISSETUID(nvap) && nvap->na_uid == nfsrv_defaultuid)
|
||||
|| (NFSVNO_ISSETGID(nvap) && nvap->na_gid == nfsrv_defaultgid))
|
||||
return (NFSERR_BADOWNER);
|
||||
|| (NFSVNO_ISSETGID(nvap) && nvap->na_gid == nfsrv_defaultgid)) {
|
||||
error = NFSERR_BADOWNER;
|
||||
goto out;
|
||||
}
|
||||
if (nd->nd_cred->cr_uid == 0)
|
||||
return (0);
|
||||
goto out;
|
||||
if ((NFSVNO_ISSETUID(nvap) && nvap->na_uid != nd->nd_cred->cr_uid) ||
|
||||
(NFSVNO_ISSETGID(nvap) && nvap->na_gid != nd->nd_cred->cr_gid &&
|
||||
!groupmember(nvap->na_gid, nd->nd_cred)))
|
||||
return (NFSERR_PERM);
|
||||
return (0);
|
||||
error = NFSERR_PERM;
|
||||
|
||||
out:
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1542,7 +1551,7 @@ nfsrv_fixattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
* the V2 and 3 semantics.
|
||||
*/
|
||||
if ((nd->nd_flag & ND_NFSV4) == 0)
|
||||
return;
|
||||
goto out;
|
||||
NFSVNO_ATTRINIT(&nva);
|
||||
NFSZERO_ATTRBIT(&nattrbits);
|
||||
tuid = nd->nd_cred->cr_uid;
|
||||
@ -1604,6 +1613,9 @@ nfsrv_fixattr(struct nfsrv_descript *nd, vnode_t vp,
|
||||
#endif
|
||||
NFSCLRBIT_ATTRBIT(attrbitp, NFSATTRBIT_ACL);
|
||||
nd->nd_cred->cr_uid = tuid;
|
||||
|
||||
out:
|
||||
NFSEXITCODE2(0, nd);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1800,10 +1812,12 @@ nfsrv_parsename(struct nfsrv_descript *nd, char *bufp, u_long *hashp,
|
||||
len = fxdr_unsigned(int, *tl);
|
||||
if (len > NFS_MAXNAMLEN) {
|
||||
nd->nd_repstat = NFSERR_NAMETOL;
|
||||
return (0);
|
||||
error = 0;
|
||||
goto nfsmout;
|
||||
} else if (len <= 0) {
|
||||
nd->nd_repstat = NFSERR_INVAL;
|
||||
return (0);
|
||||
error = 0;
|
||||
goto nfsmout;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1815,14 +1829,17 @@ nfsrv_parsename(struct nfsrv_descript *nd, char *bufp, u_long *hashp,
|
||||
for (i = 0; i < len; i++) {
|
||||
while (rem == 0) {
|
||||
md = mbuf_next(md);
|
||||
if (md == NULL)
|
||||
return (EBADRPC);
|
||||
if (md == NULL) {
|
||||
error = EBADRPC;
|
||||
goto nfsmout;
|
||||
}
|
||||
fromcp = NFSMTOD(md, caddr_t);
|
||||
rem = mbuf_len(md);
|
||||
}
|
||||
if (*fromcp == '\0') {
|
||||
nd->nd_repstat = EACCES;
|
||||
return (0);
|
||||
error = 0;
|
||||
goto nfsmout;
|
||||
}
|
||||
/*
|
||||
* For lookups on the public filehandle, do some special
|
||||
@ -1858,7 +1875,8 @@ nfsrv_parsename(struct nfsrv_descript *nd, char *bufp, u_long *hashp,
|
||||
*/
|
||||
if (*fromcp == '/' && pubtype != 1) {
|
||||
nd->nd_repstat = EACCES;
|
||||
return (0);
|
||||
error = 0;
|
||||
goto nfsmout;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1871,7 +1889,8 @@ nfsrv_parsename(struct nfsrv_descript *nd, char *bufp, u_long *hashp,
|
||||
digit = nfsrv_hexdigit(*fromcp, &error);
|
||||
if (error) {
|
||||
nd->nd_repstat = EACCES;
|
||||
return (0);
|
||||
error = 0;
|
||||
goto nfsmout;
|
||||
}
|
||||
if (percent == 1) {
|
||||
val = (digit << 4);
|
||||
@ -1890,7 +1909,8 @@ nfsrv_parsename(struct nfsrv_descript *nd, char *bufp, u_long *hashp,
|
||||
*/
|
||||
if ((len - i) < 3) {
|
||||
nd->nd_repstat = EACCES;
|
||||
return (0);
|
||||
error = 0;
|
||||
goto nfsmout;
|
||||
}
|
||||
percent = 1;
|
||||
} else {
|
||||
@ -1908,7 +1928,8 @@ nfsrv_parsename(struct nfsrv_descript *nd, char *bufp, u_long *hashp,
|
||||
nd->nd_repstat = NFSERR_BADNAME;
|
||||
else
|
||||
nd->nd_repstat = EACCES;
|
||||
return (0);
|
||||
error = 0;
|
||||
goto nfsmout;
|
||||
}
|
||||
hash += ((u_char)*fromcp);
|
||||
*tocp++ = *fromcp;
|
||||
@ -1926,7 +1947,7 @@ nfsrv_parsename(struct nfsrv_descript *nd, char *bufp, u_long *hashp,
|
||||
} else {
|
||||
error = nfsm_advance(nd, i, rem);
|
||||
if (error)
|
||||
return (error);
|
||||
goto nfsmout;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1939,11 +1960,13 @@ nfsrv_parsename(struct nfsrv_descript *nd, char *bufp, u_long *hashp,
|
||||
(outlen == 2 && bufp[0] == '.' &&
|
||||
bufp[1] == '.')) {
|
||||
nd->nd_repstat = NFSERR_BADNAME;
|
||||
return (0);
|
||||
error = 0;
|
||||
goto nfsmout;
|
||||
}
|
||||
if (nfsrv_checkutf8((u_int8_t *)bufp, outlen)) {
|
||||
nd->nd_repstat = NFSERR_INVAL;
|
||||
return (0);
|
||||
error = 0;
|
||||
goto nfsmout;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1952,6 +1975,7 @@ nfsrv_parsename(struct nfsrv_descript *nd, char *bufp, u_long *hashp,
|
||||
if (hashp != NULL)
|
||||
*hashp = hash;
|
||||
nfsmout:
|
||||
NFSEXITCODE2(error, nd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user