Module Name:    src
Committed By:   snj
Date:           Mon Apr 13 21:06:50 UTC 2009

Modified Files:
        src/sys/nfs [netbsd-5]: nfs_serv.c nfsm_subs.h

Log Message:
Pull up following revision(s) (requested by ad in ticket #700):
        sys/nfs/nfs_serv.c: revision 1.144
        sys/nfs/nfsm_subs.h: revision 1.51
PR kern/41158: nfs_rename() locking against myself
nfsrv_rename() can exit without calling genfs_renamelock_exit() because
the nfsm_reply() can do return (0) on error.
Change nfsm_reply to use 'error = 0; goto nfsmout' instead.
Fix a few place so it's safe to goto nfsmout from nfsm_reply, or other
macros calling it.
As a side effect it could fix a missing vrele(dirp) in various place where
nfsm_reply could return(0).


To generate a diff of this commit:
cvs rdiff -u -r1.138 -r1.138.16.1 src/sys/nfs/nfs_serv.c
cvs rdiff -u -r1.50 -r1.50.52.1 src/sys/nfs/nfsm_subs.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/nfs/nfs_serv.c
diff -u src/sys/nfs/nfs_serv.c:1.138 src/sys/nfs/nfs_serv.c:1.138.16.1
--- src/sys/nfs/nfs_serv.c:1.138	Fri Mar 28 05:02:08 2008
+++ src/sys/nfs/nfs_serv.c	Mon Apr 13 21:06:50 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: nfs_serv.c,v 1.138 2008/03/28 05:02:08 dholland Exp $	*/
+/*	$NetBSD: nfs_serv.c,v 1.138.16.1 2009/04/13 21:06:50 snj Exp $	*/
 
 /*
  * Copyright (c) 1989, 1993
@@ -55,7 +55,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nfs_serv.c,v 1.138 2008/03/28 05:02:08 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nfs_serv.c,v 1.138.16.1 2009/04/13 21:06:50 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1383,7 +1383,7 @@
 	int32_t t1;
 	char *bpos;
 	int error = 0, cache = 0, len, tsize, dirfor_ret = 1, diraft_ret = 1;
-	int rdev = 0;
+	int rdev = 0, abort = 0;
 	int v3 = (nfsd->nd_flag & ND_NFSV3), how, exclusive_flag = 0;
 	char *cp2;
 	struct mbuf *mb, *mreq;
@@ -1410,6 +1410,7 @@
 			vrele(dirp);
 		return (0);
 	}
+	abort = 1;
 	VATTR_NULL(&va);
 	if (v3) {
 		va.va_mode = 0;
@@ -1485,6 +1486,7 @@
 			    KAUTH_SYSTEM_MKNOD, 0, NULL, NULL, NULL))) {
 				VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
 				vput(nd.ni_dvp);
+				abort = 0;
 				nfsm_reply(0);
 				return (error);
 			} else
@@ -1500,12 +1502,14 @@
 				vrele(nd.ni_dvp);
 				VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
 				error = EINVAL;
+				abort = 0;
 				nfsm_reply(0);
 			}
 		} else {
 			VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
 			vput(nd.ni_dvp);
 			error = ENXIO;
+			abort = 0;
 		}
 		vp = nd.ni_vp;
 	} else {
@@ -1515,6 +1519,7 @@
 			vrele(nd.ni_dvp);
 		else
 			vput(nd.ni_dvp);
+		abort = 0;
 		if (!error && va.va_size != -1) {
 			error = nfsrv_access(vp, VWRITE, cred,
 			    (nd.ni_cnd.cn_flags & RDONLY), lwp, 0);
@@ -1552,7 +1557,9 @@
 	}
 	if (dirp) {
 		vrele(dirp);
+		dirp = NULL;
 	}
+	abort = 0;
 	nfsm_reply(NFSX_SRVFH(&nsfh, v3) + NFSX_FATTR(v3) + NFSX_WCCDATA(v3));
 	if (v3) {
 		if (!error) {
@@ -1569,13 +1576,15 @@
 nfsmout:
 	if (dirp)
 		vrele(dirp);
-	VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
-	if (nd.ni_dvp == nd.ni_vp)
-		vrele(nd.ni_dvp);
-	else
-		vput(nd.ni_dvp);
-	if (nd.ni_vp)
-		vput(nd.ni_vp);
+	if (abort) {
+		VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
+		if (nd.ni_dvp == nd.ni_vp)
+			vrele(nd.ni_dvp);
+		else
+			vput(nd.ni_dvp);
+		if (nd.ni_vp)
+			vput(nd.ni_vp);
+	}
 	return (error);
 }
 
@@ -1599,6 +1608,7 @@
 	int32_t t1;
 	char *bpos;
 	int error = 0, cache = 0, len, dirfor_ret = 1, diraft_ret = 1;
+	int abort = 0;
 	u_int32_t major, minor;
 	enum vtype vtyp;
 	char *cp2;
@@ -1624,6 +1634,7 @@
 			vrele(dirp);
 		return (0);
 	}
+	abort = 1;
 	nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
 	vtyp = nfsv3tov_type(*tl);
 	if (vtyp != VCHR && vtyp != VBLK && vtyp != VSOCK && vtyp != VFIFO) {
@@ -1695,7 +1706,9 @@
 	if (dirp) {
 		diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
 		vrele(dirp);
+		dirp = NULL;
 	}
+	abort = 0;
 	nfsm_reply(NFSX_SRVFH(&nsfh, true) + NFSX_POSTOPATTR(1) +
 	    NFSX_WCCDATA(1));
 	if (!error) {
@@ -1705,13 +1718,15 @@
 	nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
 	return (0);
 nfsmout:
-	VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
-	if (nd.ni_dvp == nd.ni_vp)
-		vrele(nd.ni_dvp);
-	else
-		vput(nd.ni_dvp);
-	if (nd.ni_vp)
-		vput(nd.ni_vp);
+	if (abort) {
+		VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
+		if (nd.ni_dvp == nd.ni_vp)
+			vrele(nd.ni_dvp);
+		else
+			vput(nd.ni_dvp);
+		if (nd.ni_vp)
+			vput(nd.ni_vp);
+	}
 	if (dirp)
 		vrele(dirp);
 	return (error);
@@ -2009,21 +2024,26 @@
 	}
 	vrele(tond.ni_startdir);
 	PNBUF_PUT(tond.ni_cnd.cn_pnbuf);
+	tond.ni_cnd.cn_nameiop = 0;
 out1:
 	if (fdirp) {
 		if (v3) {
 			fdiraft_ret = VOP_GETATTR(fdirp, &fdiraft, cred);
 		}
 		vrele(fdirp);
+		fdirp = NULL;
 	}
 	if (tdirp) {
 		if (v3) {
 			tdiraft_ret = VOP_GETATTR(tdirp, &tdiraft, cred);
 		}
 		vrele(tdirp);
+		tdirp = NULL;
 	}
 	vrele(fromnd.ni_startdir);
 	PNBUF_PUT(fromnd.ni_cnd.cn_pnbuf);
+	fromnd.ni_cnd.cn_nameiop = 0;
+	localfs = NULL;
 	nfsm_reply(2 * NFSX_WCCDATA(v3));
 	if (v3) {
 		nfsm_srvwcc_data(fdirfor_ret, &fdirfor, fdiraft_ret, &fdiraft);
@@ -2170,7 +2190,7 @@
 	char *bpos, *pathcp = NULL, *cp2;
 	struct uio io;
 	struct iovec iv;
-	int error = 0, cache = 0, dirfor_ret = 1, diraft_ret = 1;
+	int error = 0, cache = 0, dirfor_ret = 1, diraft_ret = 1, abort = 0;
 	uint32_t len, len2;
 	int v3 = (nfsd->nd_flag & ND_NFSV3);
 	struct mbuf *mb, *mreq;
@@ -2191,6 +2211,7 @@
 	}
 	if (error)
 		goto out;
+	abort = 1;
 	VATTR_NULL(&va);
 	va.va_type = VLNK;
 	if (v3) {
@@ -2255,7 +2276,9 @@
 			diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
 		}
 		vrele(dirp);
+		dirp = NULL;
 	}
+	abort = 0;
 	nfsm_reply(NFSX_SRVFH(&nsfh, v3) + NFSX_POSTOPATTR(v3) +
 	    NFSX_WCCDATA(v3));
 	if (v3) {
@@ -2267,13 +2290,15 @@
 	}
 	return (0);
 nfsmout:
-	VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
-	if (nd.ni_dvp == nd.ni_vp)
-		vrele(nd.ni_dvp);
-	else
-		vput(nd.ni_dvp);
-	if (nd.ni_vp)
-		vrele(nd.ni_vp);
+	if (abort) {
+		VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
+		if (nd.ni_dvp == nd.ni_vp)
+			vrele(nd.ni_dvp);
+		else
+			vput(nd.ni_dvp);
+		if (nd.ni_vp)
+			vrele(nd.ni_vp);
+	}
 	if (dirp)
 		vrele(dirp);
 	if (pathcp)
@@ -2303,6 +2328,7 @@
 	int32_t t1;
 	char *bpos;
 	int error = 0, cache = 0, len, dirfor_ret = 1, diraft_ret = 1;
+	int abort = 0;
 	int v3 = (nfsd->nd_flag & ND_NFSV3);
 	char *cp2;
 	struct mbuf *mb, *mreq;
@@ -2327,6 +2353,7 @@
 			vrele(dirp);
 		return (0);
 	}
+	abort = 1;
 	VATTR_NULL(&va);
 	if (v3) {
 		va.va_mode = 0;
@@ -2362,7 +2389,9 @@
 			diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
 		}
 		vrele(dirp);
+		dirp = NULL;
 	}
+	abort = 0;
 	nfsm_reply(NFSX_SRVFH(&nsfh, v3) + NFSX_POSTOPATTR(v3) +
 	    NFSX_WCCDATA(v3));
 	if (v3) {
@@ -2378,13 +2407,15 @@
 	}
 	return (0);
 nfsmout:
-	VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
-	if (nd.ni_dvp == nd.ni_vp)
-		vrele(nd.ni_dvp);
-	else
-		vput(nd.ni_dvp);
-	if (nd.ni_vp)
-		vrele(nd.ni_vp);
+	if (abort) {
+		VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
+		if (nd.ni_dvp == nd.ni_vp)
+			vrele(nd.ni_dvp);
+		else
+			vput(nd.ni_dvp);
+		if (nd.ni_vp)
+			vrele(nd.ni_vp);
+	}
 	if (dirp)
 		vrele(dirp);
 	return (error);
@@ -3395,6 +3426,7 @@
 	u_quad_t frev;
 
 	nfsm_reply(0);
+nfsmout:
 	return (0);
 }
 
@@ -3417,6 +3449,7 @@
 	else
 		error = EPROCUNAVAIL;
 	nfsm_reply(0);
+nfsmout:
 	return (0);
 }
 

Index: src/sys/nfs/nfsm_subs.h
diff -u src/sys/nfs/nfsm_subs.h:1.50 src/sys/nfs/nfsm_subs.h:1.50.52.1
--- src/sys/nfs/nfsm_subs.h:1.50	Sun Mar  4 06:03:38 2007
+++ src/sys/nfs/nfsm_subs.h	Mon Apr 13 21:06:50 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: nfsm_subs.h,v 1.50 2007/03/04 06:03:38 christos Exp $	*/
+/*	$NetBSD: nfsm_subs.h,v 1.50.52.1 2009/04/13 21:06:50 snj Exp $	*/
 
 /*
  * Copyright (c) 1989, 1993
@@ -444,8 +444,10 @@
 		} \
 		mreq = *mrq; \
 		if (error && (!(nfsd->nd_flag & ND_NFSV3) || \
-			error == EBADRPC)) \
-			return(0); \
+			error == EBADRPC)) {\
+			error = 0; \
+			goto nfsmout; \
+			} \
 		}
 
 #define	nfsm_writereply(s, v3) \

Reply via email to