Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 13 Aug 2011 17:21:50 +0000 (UTC)
From:      Zack Kirsch <zack@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r224851 - in stable/8/sys/fs: nfs nfsserver
Message-ID:  <201108131721.p7DHLoo3025993@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: zack
Date: Sat Aug 13 17:21:50 2011
New Revision: 224851
URL: http://svn.freebsd.org/changeset/base/224851

Log:
  MFC r224086:
  
  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>

Modified:
  stable/8/sys/fs/nfs/nfs_commonacl.c
  stable/8/sys/fs/nfs/nfs_commonkrpc.c
  stable/8/sys/fs/nfs/nfs_commonport.c
  stable/8/sys/fs/nfs/nfs_commonsubs.c
  stable/8/sys/fs/nfs/nfsdport.h
  stable/8/sys/fs/nfsserver/nfs_nfsdcache.c
  stable/8/sys/fs/nfsserver/nfs_nfsdkrpc.c
  stable/8/sys/fs/nfsserver/nfs_nfsdport.c
  stable/8/sys/fs/nfsserver/nfs_nfsdserv.c
  stable/8/sys/fs/nfsserver/nfs_nfsdsocket.c
  stable/8/sys/fs/nfsserver/nfs_nfsdstate.c
  stable/8/sys/fs/nfsserver/nfs_nfsdsubs.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/fs/nfs/nfs_commonacl.c
==============================================================================
--- stable/8/sys/fs/nfs/nfs_commonacl.c	Sat Aug 13 17:20:00 2011	(r224850)
+++ stable/8/sys/fs/nfs/nfs_commonacl.c	Sat Aug 13 17:21:50 2011	(r224851)
@@ -59,7 +59,8 @@ nfsrv_dissectace(struct nfsrv_descript *
 	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 *
 		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 *
 	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 *
 	*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
     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
 		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,
 {
 	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);
 }
 

Modified: stable/8/sys/fs/nfs/nfs_commonkrpc.c
==============================================================================
--- stable/8/sys/fs/nfs/nfs_commonkrpc.c	Sat Aug 13 17:20:00 2011	(r224850)
+++ stable/8/sys/fs/nfs/nfs_commonkrpc.c	Sat Aug 13 17:21:50 2011	(r224851)
@@ -143,7 +143,7 @@ newnfs_connect(struct nfsmount *nmp, str
 	CLIENT *client;
 	struct netconfig *nconf;
 	struct socket *so;
-	int one = 1, retries, error;
+	int one = 1, retries, error = 0;
 	struct thread *td = curthread;
 
 	/*
@@ -199,7 +199,7 @@ newnfs_connect(struct nfsmount *nmp, str
 	    nrp->nr_soproto, td->td_ucred, td);
 	if (error) {
 		td->td_ucred = origcred;
-		return (error);
+		goto out;
 	}
 	do {
 	    if (error != 0 && pktscale > 2)
@@ -230,7 +230,7 @@ newnfs_connect(struct nfsmount *nmp, str
 	soclose(so);
 	if (error) {
 		td->td_ucred = origcred;
-		return (error);
+		goto out;
 	}
 
 	client = clnt_reconnect_create(nconf, saddr, nrp->nr_prog,
@@ -284,7 +284,10 @@ newnfs_connect(struct nfsmount *nmp, str
 
 	/* Restore current thread's credentials. */
 	td->td_ucred = origcred;
-	return (0);
+
+out:
+	NFSEXITCODE(error);
+	return (error);
 }
 
 /*

Modified: stable/8/sys/fs/nfs/nfs_commonport.c
==============================================================================
--- stable/8/sys/fs/nfs/nfs_commonport.c	Sat Aug 13 17:20:00 2011	(r224850)
+++ stable/8/sys/fs/nfs/nfs_commonport.c	Sat Aug 13 17:21:50 2011	(r224851)
@@ -331,6 +331,7 @@ nfsvno_pathconf(struct vnode *vp, int fl
 		};
 		error = 0;
 	}
+	NFSEXITCODE(error);
 	return (error);
 }
 
@@ -429,6 +430,7 @@ nfssvc_nfscommon(struct thread *td, stru
 	int error;
 
 	error = nfssvc_call(td, uap, td->td_ucred);
+	NFSEXITCODE(error);
 	return (error);
 }
 
@@ -441,9 +443,9 @@ nfssvc_call(struct thread *p, struct nfs
 	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));
@@ -505,7 +507,7 @@ nfssvc_call(struct thread *p, struct nfs
 				    sizeof(newnfsstats.cbrpccnt));
 			}
 		}
-		return (error);
+		goto out;
 	} else if (uap->flag & NFSSVC_NFSUSERDPORT) {
 		u_short sockport;
 
@@ -517,6 +519,9 @@ nfssvc_call(struct thread *p, struct nfs
 		nfsrv_nfsuserddelport();
 		error = 0;
 	}
+
+out:
+	NFSEXITCODE(error);
 	return (error);
 }
 
@@ -571,7 +576,7 @@ nfscommon_modevent(module_t mod, int typ
 	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);
@@ -608,6 +613,9 @@ nfscommon_modevent(module_t mod, int typ
 		error = EOPNOTSUPP;
 		break;
 	}
+
+out:
+	NFSEXITCODE(error);
 	return error;
 }
 static moduledata_t nfscommon_mod = {

Modified: stable/8/sys/fs/nfs/nfs_commonsubs.c
==============================================================================
--- stable/8/sys/fs/nfs/nfs_commonsubs.c	Sat Aug 13 17:20:00 2011	(r224850)
+++ stable/8/sys/fs/nfs/nfs_commonsubs.c	Sat Aug 13 17:21:50 2011	(r224851)
@@ -179,8 +179,10 @@ nfsm_mbufuio(struct nfsrv_descript *nd, 
 	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, 
 		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, 
 		else
 			nd->nd_dpos += rem;
 	}
+
+out:
+	NFSEXITCODE2(error, nd);
 	return (error);
 }
 #endif	/* !APPLE */
@@ -308,9 +315,10 @@ nfsm_dissct(struct nfsrv_descript *nd, i
 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, 
 	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, st
 	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, st
 	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 *
 		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 *
 	if (aclsizep)
 		*aclsizep = aclsize;
 nfsmout:
+	NFSEXITCODE2(error, nd);
 	return (error);
 }
 
@@ -697,6 +714,7 @@ nfsrv_skipace(struct nfsrv_descript *nd,
 	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 
 
 	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 
 	if (cntp)
 		*cntp = NFSX_UNSIGNED + (cnt * NFSX_UNSIGNED);
 nfsmout:
+	NFSEXITCODE2(error, nd);
 	return (error);
 }
 
@@ -756,7 +777,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd
     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;
@@ -782,7 +803,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd
 		error = nfsrv_getattrbits(nd, &attrbits, NULL, NULL);
 	}
 	if (error)
-		return (error);
+		goto nfsmout;
 
 	if (compare) {
 		*retcmpp = retnotsup;
@@ -853,7 +874,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd
 			    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)
@@ -1014,7 +1035,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd
 				    &cnt, p);
 				if (error) {
 				    acl_free(naclp);
-				    return (error);
+				    goto nfsmout;
 				}
 				if (aceerr || nfsrv_compareacl(aclp, naclp))
 				    *retcmpp = NFSERR_NOTSAME;
@@ -1033,7 +1054,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd
 				error = nfsrv_dissectacl(nd, NULL, &aceerr,
 				    &cnt, p);
 			    if (error)
-				return (error);
+				goto nfsmout;
 			}
 			attrsum += cnt;
 			break;
@@ -1118,7 +1139,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd
 		case NFSATTRBIT_FILEHANDLE:
 			error = nfsm_getfh(nd, &tnfhp);
 			if (error)
-				return (error);
+				goto nfsmout;
 			tfhsize = tnfhp->nfh_len;
 			if (compare) {
 				if (!(*retcmpp) &&
@@ -1184,7 +1205,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd
 		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);
@@ -1360,8 +1381,10 @@ nfsv4_loadattr(struct nfsrv_descript *nd
 		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);
@@ -1371,7 +1394,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd
 			if (error) {
 				if (j > NFSV4_SMALLSTR)
 					free(cp, M_NFSSTRING);
-				return (error);
+				goto nfsmout;
 			}
 			if (compare) {
 			    if (!(*retcmpp)) {
@@ -1391,8 +1414,10 @@ nfsv4_loadattr(struct nfsrv_descript *nd
 		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);
@@ -1402,7 +1427,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd
 			if (error) {
 				if (j > NFSV4_SMALLSTR)
 					free(cp, M_NFSSTRING);
-				return (error);
+				goto nfsmout;
 			}
 			if (compare) {
 			    if (!(*retcmpp)) {
@@ -1708,6 +1733,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd
 			error = nfsm_advance(nd, attrsize - attrsum, -1);
 	}
 nfsmout:
+	NFSEXITCODE2(error, nd);
 	return (error);
 }
 
@@ -1904,8 +1930,10 @@ nfsrv_mtostr(struct nfsrv_descript *nd, 
 		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 {
@@ -1922,6 +1950,9 @@ nfsrv_mtostr(struct nfsrv_descript *nd, 
 		else
 			nd->nd_dpos += rem;
 	}
+
+out:
+	NFSEXITCODE2(error, nd);
 	return (error);
 }
 
@@ -2568,9 +2599,12 @@ nfsv4_strtouid(u_char *str, int len, uid
 	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 '@'.
 	 */
@@ -2601,7 +2635,8 @@ tryagain:
 	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) {
@@ -2613,7 +2648,8 @@ tryagain:
 			TAILQ_REMOVE(&nfsuserlruhead, usrp, lug_lru);
 			TAILQ_INSERT_TAIL(&nfsuserlruhead, usrp, lug_lru);
 			NFSUNLOCKNAMEID();
-			return (0);
+			error = 0;
+			goto out;
 		}
 	}
 	NFSUNLOCKNAMEID();
@@ -2622,7 +2658,11 @@ tryagain:
 	    str, p);
 	if (ret == 0 && cnt < 2)
 		goto tryagain;
-	return (NFSERR_BADOWNER);
+	error = NFSERR_BADOWNER;
+
+out:
+	NFSEXITCODE(error);
+	return (error);
 }
 
 /*
@@ -2748,9 +2788,12 @@ nfsv4_strtogid(u_char *str, int len, gid
 	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 '@'.
 	 */
@@ -2779,7 +2822,8 @@ tryagain:
 	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) {
@@ -2791,7 +2835,8 @@ tryagain:
 			TAILQ_REMOVE(&nfsuserlruhead, usrp, lug_lru);
 			TAILQ_INSERT_TAIL(&nfsuserlruhead, usrp, lug_lru);
 			NFSUNLOCKNAMEID();
-			return (0);
+			error = 0;
+			goto out;
 		}
 	}
 	NFSUNLOCKNAMEID();
@@ -2800,7 +2845,11 @@ tryagain:
 	    str, p);
 	if (ret == 0 && cnt < 2)
 		goto tryagain;
-	return (NFSERR_BADOWNER);
+	error = NFSERR_BADOWNER;
+
+out:
+	NFSEXITCODE(error);
+	return (error);
 }
 
 /*
@@ -2845,7 +2894,8 @@ nfsrv_nfsuserdport(u_short port, NFSPROC
 	NFSLOCKNAMEID();
 	if (nfsrv_nfsuserd) {
 		NFSUNLOCKNAMEID();
-		return (EPERM);
+		error = EPERM;
+		goto out;
 	}
 	nfsrv_nfsuserd = 1;
 	NFSUNLOCKNAMEID();
@@ -2871,6 +2921,8 @@ nfsrv_nfsuserdport(u_short port, NFSPROC
 		NFSSOCKADDRFREE(rp->nr_nam);
 		nfsrv_nfsuserd = 0;
 	}
+out:
+	NFSEXITCODE(error);
 	return (error);
 }
 
@@ -2910,7 +2962,8 @@ nfsrv_getuser(int procnum, uid_t uid, gi
 	NFSLOCKNAMEID();
 	if (nfsrv_nfsuserd == 0) {
 		NFSUNLOCKNAMEID();
-		return (EPERM);
+		error = EPERM;
+		goto out;
 	}
 	NFSUNLOCKNAMEID();
 	nd = &nfsd;
@@ -2936,6 +2989,8 @@ nfsrv_getuser(int procnum, uid_t uid, gi
 		mbuf_freem(nd->nd_mrep);
 		error = nd->nd_repstat;
 	}
+out:
+	NFSEXITCODE(error);
 	return (error);
 }
 
@@ -2992,7 +3047,7 @@ nfssvc_idname(struct nfsd_idargs *nidp)
 	    NFSUNLOCKNAMEID();
 	    if (error)
 		free(cp, M_NFSSTRING);
-	    return (error);
+	    goto out;
 	}
 
 	/*
@@ -3005,7 +3060,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;
 
@@ -3080,6 +3135,8 @@ nfssvc_idname(struct nfsd_idargs *nidp)
 	} else
 		FREE((caddr_t)newusrp, M_NFSUSERGROUP);
 	NFSUNLOCKNAMEID();
+out:
+	NFSEXITCODE(error);
 	return (error);
 }
 
@@ -3109,6 +3166,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:
@@ -3125,14 +3183,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;
@@ -3140,8 +3202,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)
@@ -3152,8 +3216,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);
 }
 
 /*
@@ -3174,7 +3241,7 @@ nfsrv_getrefstr(struct nfsrv_descript *n
 {
 	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;
@@ -3192,15 +3259,20 @@ nfsrv_getrefstr(struct nfsrv_descript *n
 	 */
 	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);
@@ -3210,10 +3282,8 @@ nfsrv_getrefstr(struct nfsrv_descript *n
 		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.
@@ -3227,9 +3297,8 @@ nfsrv_getrefstr(struct nfsrv_descript *n
 		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;
 		}
 
 		/*
@@ -3238,9 +3307,8 @@ nfsrv_getrefstr(struct nfsrv_descript *n
 		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) {
@@ -3248,11 +3316,8 @@ nfsrv_getrefstr(struct nfsrv_descript *n
 			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);
@@ -3264,18 +3329,14 @@ nfsrv_getrefstr(struct nfsrv_descript *n
 			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);
@@ -3287,17 +3348,13 @@ nfsrv_getrefstr(struct nfsrv_descript *n
 		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;
@@ -3320,12 +3377,14 @@ nfsrv_getrefstr(struct nfsrv_descript *n
 	*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);
 }
 

Modified: stable/8/sys/fs/nfs/nfsdport.h
==============================================================================
--- stable/8/sys/fs/nfs/nfsdport.h	Sat Aug 13 17:20:00 2011	(r224850)
+++ stable/8/sys/fs/nfs/nfsdport.h	Sat Aug 13 17:21:50 2011	(r224851)
@@ -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)

Modified: stable/8/sys/fs/nfsserver/nfs_nfsdcache.c
==============================================================================
--- stable/8/sys/fs/nfsserver/nfs_nfsdcache.c	Sat Aug 13 17:20:00 2011	(r224850)
+++ stable/8/sys/fs/nfsserver/nfs_nfsdcache.c	Sat Aug 13 17:21:50 2011	(r224851)
@@ -308,6 +308,7 @@ nfsrvd_getcache(struct nfsrv_descript *n
 		ret = nfsrc_gettcp(nd, newrp);
 	}
 	nfsrc_trimcache(nd->nd_sockref, so);
+	NFSEXITCODE2(0, nd);
 	return (ret);
 }
 
@@ -373,7 +374,7 @@ loop:
 			}
 			nfsrc_unlock(rp);
 			free((caddr_t)newrp, M_NFSRVCACHE);
-			return (ret);
+			goto out;
 		}
 	}
 	newnfsstats.srvcache_misses++;
@@ -394,7 +395,11 @@ loop:
 	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
 		    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
 		nfsrc_freecache(rp);
 		NFSUNLOCKCACHE();
 	}
+
+out:
 	nfsrc_trimcache(nd->nd_sockref, so);
+	NFSEXITCODE2(0, nd);
 	return (retrp);
 }
 
@@ -656,7 +663,7 @@ tryagain:
 		}
 		nfsrc_unlock(rp);
 		free((caddr_t)newrp, M_NFSRVCACHE);
-		return (ret);
+		goto out;
 	}
 	newnfsstats.srvcache_misses++;
 	newnfsstats.srvcache_size++;
@@ -670,7 +677,11 @@ tryagain:
 	LIST_INSERT_HEAD(hp, newrp, rc_hash);
 	NFSUNLOCKCACHE();
 	nd->nd_rp = newrp;
-	return (RC_DOIT);
+	ret = RC_DOIT;
+
+out:
+	NFSEXITCODE2(0, nd);
+	return (ret);
 }
 
 /*

Modified: stable/8/sys/fs/nfsserver/nfs_nfsdkrpc.c
==============================================================================
--- stable/8/sys/fs/nfsserver/nfs_nfsdkrpc.c	Sat Aug 13 17:20:00 2011	(r224850)
+++ stable/8/sys/fs/nfsserver/nfs_nfsdkrpc.c	Sat Aug 13 17:21:50 2011	(r224851)
@@ -115,7 +115,7 @@ nfssvc_program(struct svc_req *rqst, SVC
 		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, SVC
 		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, SVC
 		    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, SVC
 			svcerr_weakauth(rqst);
 			svc_freereq(rqst);
 			m_freem(nd.nd_mrep);
-			return;
+			goto out;
 		}
 	}
 
@@ -201,7 +201,7 @@ nfssvc_program(struct svc_req *rqst, SVC
 			svcerr_weakauth(rqst);
 			svc_freereq(rqst);
 			m_freem(nd.nd_mrep);
-			return;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201108131721.p7DHLoo3025993>