Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 24 Aug 2009 10:09:30 +0000 (UTC)
From:      Marko Zec <zec@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r196503 - in head/sys: fs/nfsclient nfsclient rpc
Message-ID:  <200908241009.n7OA9UqT089224@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: zec
Date: Mon Aug 24 10:09:30 2009
New Revision: 196503
URL: http://svn.freebsd.org/changeset/base/196503

Log:
  Fix NFS panics with options VIMAGE kernels by apropriately setting curvnet
  context inside the RPC code.
  
  Temporarily set td's cred to mount's cred before calling socreate() via
  __rpc_nconf2socket().
  
  Submitted by:	rmacklem (in part)
  Reviewed by:	rmacklem, rwatson
  Discussed with:	dfr, bz
  Approved by:	re (rwatson), julian (mentor)
  MFC after:	3 days

Modified:
  head/sys/fs/nfsclient/nfs_clvnops.c
  head/sys/nfsclient/nfs_vnops.c
  head/sys/rpc/clnt_dg.c
  head/sys/rpc/clnt_rc.c
  head/sys/rpc/clnt_vc.c
  head/sys/rpc/rpc_generic.c
  head/sys/rpc/svc_dg.c
  head/sys/rpc/svc_generic.c
  head/sys/rpc/svc_vc.c

Modified: head/sys/fs/nfsclient/nfs_clvnops.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clvnops.c	Mon Aug 24 10:06:02 2009	(r196502)
+++ head/sys/fs/nfsclient/nfs_clvnops.c	Mon Aug 24 10:09:30 2009	(r196503)
@@ -1405,8 +1405,8 @@ again:
 	}
 	mtx_unlock(&dnp->n_mtx);
 
-	CURVNET_SET(P_TO_VNET(&proc0));
 #ifdef INET
+	CURVNET_SET(CRED_TO_VNET(cnp->cn_cred));
 	IN_IFADDR_RLOCK();
 	if (!TAILQ_EMPTY(&V_in_ifaddrhead))
 		cverf.lval[0] = IA_SIN(TAILQ_FIRST(&V_in_ifaddrhead))->sin_addr.s_addr;
@@ -1415,9 +1415,9 @@ again:
 		cverf.lval[0] = create_verf;
 #ifdef INET
 	IN_IFADDR_RUNLOCK();
+	CURVNET_RESTORE();
 #endif
 	cverf.lval[1] = ++create_verf;
-	CURVNET_RESTORE();
 	error = nfsrpc_create(dvp, cnp->cn_nameptr, cnp->cn_namelen,
 	    vap, cverf, fmode, cnp->cn_cred, cnp->cn_thread, &dnfsva, &nfsva,
 	    &nfhp, &attrflag, &dattrflag, NULL);

Modified: head/sys/nfsclient/nfs_vnops.c
==============================================================================
--- head/sys/nfsclient/nfs_vnops.c	Mon Aug 24 10:06:02 2009	(r196502)
+++ head/sys/nfsclient/nfs_vnops.c	Mon Aug 24 10:09:30 2009	(r196503)
@@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/mount.h>
 #include <sys/bio.h>
 #include <sys/buf.h>
+#include <sys/jail.h>
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
 #include <sys/namei.h>
@@ -1552,6 +1553,7 @@ again:
 			*tl = txdr_unsigned(NFSV3CREATE_EXCLUSIVE);
 			tl = nfsm_build(u_int32_t *, NFSX_V3CREATEVERF);
 #ifdef INET
+			CURVNET_SET(CRED_TO_VNET(cnp->cn_cred));
 			IN_IFADDR_RLOCK();
 			if (!TAILQ_EMPTY(&V_in_ifaddrhead))
 				*tl++ = IA_SIN(TAILQ_FIRST(&V_in_ifaddrhead))->sin_addr.s_addr;
@@ -1560,6 +1562,7 @@ again:
 				*tl++ = create_verf;
 #ifdef INET
 			IN_IFADDR_RUNLOCK();
+			CURVNET_RESTORE();
 #endif
 			*tl = ++create_verf;
 		} else {

Modified: head/sys/rpc/clnt_dg.c
==============================================================================
--- head/sys/rpc/clnt_dg.c	Mon Aug 24 10:06:02 2009	(r196502)
+++ head/sys/rpc/clnt_dg.c	Mon Aug 24 10:09:30 2009	(r196503)
@@ -57,6 +57,8 @@ __FBSDID("$FreeBSD$");
 #include <sys/time.h>
 #include <sys/uio.h>
 
+#include <net/vnet.h>
+
 #include <rpc/rpc.h>
 #include <rpc/rpc_com.h>
 
@@ -197,11 +199,14 @@ clnt_dg_create(
 		return (NULL);
 	}
 
+	CURVNET_SET(so->so_vnet);
 	if (!__rpc_socket2sockinfo(so, &si)) {
 		rpc_createerr.cf_stat = RPC_TLIERROR;
 		rpc_createerr.cf_error.re_errno = 0;
+		CURVNET_RESTORE();
 		return (NULL);
 	}
+	CURVNET_RESTORE();
 
 	/*
 	 * Find the receive and the send size

Modified: head/sys/rpc/clnt_rc.c
==============================================================================
--- head/sys/rpc/clnt_rc.c	Mon Aug 24 10:06:02 2009	(r196502)
+++ head/sys/rpc/clnt_rc.c	Mon Aug 24 10:09:30 2009	(r196503)
@@ -175,15 +175,16 @@ clnt_reconnect_connect(CLIENT *cl)
 	rc->rc_connecting = TRUE;
 	mtx_unlock(&rc->rc_lock);
 
+	oldcred = td->td_ucred;
+	td->td_ucred = rc->rc_ucred;
 	so = __rpc_nconf2socket(rc->rc_nconf);
 	if (!so) {
 		stat = rpc_createerr.cf_stat = RPC_TLIERROR;
 		rpc_createerr.cf_error.re_errno = 0;
+		td->td_ucred = oldcred;
 		goto out;
 	}
 
-	oldcred = td->td_ucred;
-	td->td_ucred = rc->rc_ucred;
 	if (rc->rc_privport)
 		bindresvport(so, NULL);
 

Modified: head/sys/rpc/clnt_vc.c
==============================================================================
--- head/sys/rpc/clnt_vc.c	Mon Aug 24 10:06:02 2009	(r196502)
+++ head/sys/rpc/clnt_vc.c	Mon Aug 24 10:09:30 2009	(r196503)
@@ -70,6 +70,9 @@ __FBSDID("$FreeBSD$");
 #include <sys/syslog.h>
 #include <sys/time.h>
 #include <sys/uio.h>
+
+#include <net/vnet.h>
+
 #include <netinet/tcp.h>
 
 #include <rpc/rpc.h>
@@ -217,8 +220,11 @@ clnt_vc_create(
 		}
 	}
 
-	if (!__rpc_socket2sockinfo(so, &si))
+	CURVNET_SET(so->so_vnet);
+	if (!__rpc_socket2sockinfo(so, &si)) {
+		CURVNET_RESTORE();
 		goto err;
+	}
 
 	if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
 		bzero(&sopt, sizeof(sopt));
@@ -239,6 +245,7 @@ clnt_vc_create(
 		sopt.sopt_valsize = sizeof(one);
 		sosetopt(so, &sopt);
 	}
+	CURVNET_RESTORE();
 
 	ct->ct_closeit = FALSE;
 

Modified: head/sys/rpc/rpc_generic.c
==============================================================================
--- head/sys/rpc/rpc_generic.c	Mon Aug 24 10:06:02 2009	(r196502)
+++ head/sys/rpc/rpc_generic.c	Mon Aug 24 10:09:30 2009	(r196503)
@@ -56,6 +56,8 @@ __FBSDID("$FreeBSD$");
 #include <sys/socketvar.h>
 #include <sys/syslog.h>
 
+#include <net/vnet.h>
+
 #include <rpc/rpc.h>
 #include <rpc/nettype.h>
 
@@ -822,6 +824,7 @@ bindresvport(struct socket *so, struct s
 	sa->sa_len = salen;
 
 	if (*portp == 0) {
+		CURVNET_SET(so->so_vnet);
 		bzero(&opt, sizeof(opt));
 		opt.sopt_dir = SOPT_GET;
 		opt.sopt_level = proto;
@@ -829,12 +832,15 @@ bindresvport(struct socket *so, struct s
 		opt.sopt_val = &old;
 		opt.sopt_valsize = sizeof(old);
 		error = sogetopt(so, &opt);
-		if (error)
+		if (error) {
+			CURVNET_RESTORE();
 			goto out;
+		}
 
 		opt.sopt_dir = SOPT_SET;
 		opt.sopt_val = &portlow;
 		error = sosetopt(so, &opt);
+		CURVNET_RESTORE();
 		if (error)
 			goto out;
 	}
@@ -845,7 +851,9 @@ bindresvport(struct socket *so, struct s
 		if (error) {
 			opt.sopt_dir = SOPT_SET;
 			opt.sopt_val = &old;
+			CURVNET_SET(so->so_vnet);
 			sosetopt(so, &opt);
+			CURVNET_RESTORE();
 		}
 	}
 out:

Modified: head/sys/rpc/svc_dg.c
==============================================================================
--- head/sys/rpc/svc_dg.c	Mon Aug 24 10:06:02 2009	(r196502)
+++ head/sys/rpc/svc_dg.c	Mon Aug 24 10:09:30 2009	(r196503)
@@ -57,6 +57,8 @@ __FBSDID("$FreeBSD$");
 #include <sys/systm.h>
 #include <sys/uio.h>
 
+#include <net/vnet.h>
+
 #include <rpc/rpc.h>
 
 #include <rpc/rpc_com.h>
@@ -101,8 +103,10 @@ svc_dg_create(SVCPOOL *pool, struct sock
 	struct sockaddr* sa;
 	int error;
 
+	CURVNET_SET(so->so_vnet);
 	if (!__rpc_socket2sockinfo(so, &si)) {
 		printf(svc_dg_str, svc_dg_err1);
+		CURVNET_RESTORE();
 		return (NULL);
 	}
 	/*
@@ -112,6 +116,7 @@ svc_dg_create(SVCPOOL *pool, struct sock
 	recvsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsize);
 	if ((sendsize == 0) || (recvsize == 0)) {
 		printf(svc_dg_str, svc_dg_err2);
+		CURVNET_RESTORE();
 		return (NULL);
 	}
 
@@ -124,6 +129,7 @@ svc_dg_create(SVCPOOL *pool, struct sock
 	xprt->xp_ops = &svc_dg_ops;
 
 	error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa);
+	CURVNET_RESTORE();
 	if (error)
 		goto freedata;
 

Modified: head/sys/rpc/svc_generic.c
==============================================================================
--- head/sys/rpc/svc_generic.c	Mon Aug 24 10:06:02 2009	(r196502)
+++ head/sys/rpc/svc_generic.c	Mon Aug 24 10:09:30 2009	(r196503)
@@ -60,6 +60,8 @@ __FBSDID("$FreeBSD$");
 #include <sys/sx.h>
 #include <sys/ucred.h>
 
+#include <net/vnet.h>
+
 #include <rpc/rpc.h>
 #include <rpc/rpcb_clnt.h>
 #include <rpc/nettype.h>
@@ -228,11 +230,14 @@ svc_tli_create(
 		/*
 		 * It is an open socket. Get the transport info.
 		 */
+		CURVNET_SET(so->so_vnet);
 		if (!__rpc_socket2sockinfo(so, &si)) {
 			printf(
 		"svc_tli_create: could not get transport information\n");
+			CURVNET_RESTORE();
 			return (NULL);
 		}
+		CURVNET_RESTORE();
 	}
 
 	/*
@@ -259,7 +264,9 @@ svc_tli_create(
 		"svc_tli_create: could not bind to requested address\n");
 				goto freedata;
 			}
+			CURVNET_SET(so->so_vnet);
 			solisten(so, (int)bindaddr->qlen, curthread);
+			CURVNET_RESTORE();
 		}
 			
 	}

Modified: head/sys/rpc/svc_vc.c
==============================================================================
--- head/sys/rpc/svc_vc.c	Mon Aug 24 10:06:02 2009	(r196502)
+++ head/sys/rpc/svc_vc.c	Mon Aug 24 10:09:30 2009	(r196503)
@@ -58,6 +58,9 @@ __FBSDID("$FreeBSD$");
 #include <sys/sx.h>
 #include <sys/systm.h>
 #include <sys/uio.h>
+
+#include <net/vnet.h>
+
 #include <netinet/tcp.h>
 
 #include <rpc/rpc.h>
@@ -151,9 +154,12 @@ svc_vc_create(SVCPOOL *pool, struct sock
 	xprt->xp_p2 = NULL;
 	xprt->xp_ops = &svc_vc_rendezvous_ops;
 
+	CURVNET_SET(so->so_vnet);
 	error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa);
-	if (error)
+	if (error) {
+		CURVNET_RESTORE();
 		goto cleanup_svc_vc_create;
+	}
 
 	memcpy(&xprt->xp_ltaddr, sa, sa->sa_len);
 	free(sa, M_SONAME);
@@ -161,6 +167,7 @@ svc_vc_create(SVCPOOL *pool, struct sock
 	xprt_register(xprt);
 
 	solisten(so, SOMAXCONN, curthread);
+	CURVNET_RESTORE();
 
 	SOCKBUF_LOCK(&so->so_rcv);
 	xprt->xp_upcallset = 1;
@@ -193,9 +200,12 @@ svc_vc_create_conn(SVCPOOL *pool, struct
 	opt.sopt_name = SO_KEEPALIVE;
 	opt.sopt_val = &one;
 	opt.sopt_valsize = sizeof(one);
+	CURVNET_SET(so->so_vnet);
 	error = sosetopt(so, &opt);
-	if (error)
+	if (error) {
+		CURVNET_RESTORE();
 		return (NULL);
+	}
 
 	if (so->so_proto->pr_protocol == IPPROTO_TCP) {
 		bzero(&opt, sizeof(struct sockopt));
@@ -205,9 +215,12 @@ svc_vc_create_conn(SVCPOOL *pool, struct
 		opt.sopt_val = &one;
 		opt.sopt_valsize = sizeof(one);
 		error = sosetopt(so, &opt);
-		if (error)
+		if (error) {
+			CURVNET_RESTORE();
 			return (NULL);
+		}
 	}
+	CURVNET_RESTORE();
 
 	cd = mem_alloc(sizeof(*cd));
 	cd->strm_stat = XPRT_IDLE;
@@ -625,8 +638,10 @@ svc_vc_recv(SVCXPRT *xprt, struct rpc_ms
 		uio.uio_td = curthread;
 		m = NULL;
 		rcvflag = MSG_DONTWAIT;
+		CURVNET_SET(xprt->xp_socket->so_vnet);
 		error = soreceive(xprt->xp_socket, NULL, &uio, &m, NULL,
 		    &rcvflag);
+		CURVNET_RESTORE();
 
 		if (error == EWOULDBLOCK) {
 			/*



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