diff options
author | Marko Zec <zec@FreeBSD.org> | 2009-08-24 10:09:30 +0000 |
---|---|---|
committer | Marko Zec <zec@FreeBSD.org> | 2009-08-24 10:09:30 +0000 |
commit | 0348c661d18262546ed177e4f7fd250976823944 (patch) | |
tree | 5ba9dcd2e54bc9abd1d333c3fb6c2e11842ff46f /sys/rpc | |
parent | 2b73aacaf9ab339d6aaaf256f17f298dc54c423e (diff) | |
download | src-0348c661d18262546ed177e4f7fd250976823944.tar.gz src-0348c661d18262546ed177e4f7fd250976823944.zip |
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
Notes
Notes:
svn path=/head/; revision=196503
Diffstat (limited to 'sys/rpc')
-rw-r--r-- | sys/rpc/clnt_dg.c | 5 | ||||
-rw-r--r-- | sys/rpc/clnt_rc.c | 5 | ||||
-rw-r--r-- | sys/rpc/clnt_vc.c | 9 | ||||
-rw-r--r-- | sys/rpc/rpc_generic.c | 10 | ||||
-rw-r--r-- | sys/rpc/svc_dg.c | 6 | ||||
-rw-r--r-- | sys/rpc/svc_generic.c | 7 | ||||
-rw-r--r-- | sys/rpc/svc_vc.c | 21 |
7 files changed, 56 insertions, 7 deletions
diff --git a/sys/rpc/clnt_dg.c b/sys/rpc/clnt_dg.c index 0b49375b993a..78f4a9a21285 100644 --- a/sys/rpc/clnt_dg.c +++ b/sys/rpc/clnt_dg.c @@ -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 diff --git a/sys/rpc/clnt_rc.c b/sys/rpc/clnt_rc.c index 217608c4bb36..24fc09a3605b 100644 --- a/sys/rpc/clnt_rc.c +++ b/sys/rpc/clnt_rc.c @@ -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); diff --git a/sys/rpc/clnt_vc.c b/sys/rpc/clnt_vc.c index 3f15c435c75f..85e89abe5c31 100644 --- a/sys/rpc/clnt_vc.c +++ b/sys/rpc/clnt_vc.c @@ -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; diff --git a/sys/rpc/rpc_generic.c b/sys/rpc/rpc_generic.c index d9100b340b1e..f15ad28f294a 100644 --- a/sys/rpc/rpc_generic.c +++ b/sys/rpc/rpc_generic.c @@ -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 sockaddr *sa) 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 sockaddr *sa) 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 sockaddr *sa) if (error) { opt.sopt_dir = SOPT_SET; opt.sopt_val = &old; + CURVNET_SET(so->so_vnet); sosetopt(so, &opt); + CURVNET_RESTORE(); } } out: diff --git a/sys/rpc/svc_dg.c b/sys/rpc/svc_dg.c index 0747d1d96393..9d7696b0145c 100644 --- a/sys/rpc/svc_dg.c +++ b/sys/rpc/svc_dg.c @@ -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 socket *so, size_t sendsize, 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 socket *so, size_t sendsize, 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 socket *so, size_t sendsize, xprt->xp_ops = &svc_dg_ops; error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa); + CURVNET_RESTORE(); if (error) goto freedata; diff --git a/sys/rpc/svc_generic.c b/sys/rpc/svc_generic.c index 38380f25defe..e6e8acdb1d93 100644 --- a/sys/rpc/svc_generic.c +++ b/sys/rpc/svc_generic.c @@ -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(); } } diff --git a/sys/rpc/svc_vc.c b/sys/rpc/svc_vc.c index b7da5e22787d..85d335fa015b 100644 --- a/sys/rpc/svc_vc.c +++ b/sys/rpc/svc_vc.c @@ -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 socket *so, size_t sendsize, 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 socket *so, size_t sendsize, 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 socket *so, struct sockaddr *raddr) 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 socket *so, struct sockaddr *raddr) 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_msg *msg, 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) { /* |