aboutsummaryrefslogtreecommitdiff
path: root/sys/rpc
diff options
context:
space:
mode:
authorMarko Zec <zec@FreeBSD.org>2009-08-24 10:09:30 +0000
committerMarko Zec <zec@FreeBSD.org>2009-08-24 10:09:30 +0000
commit0348c661d18262546ed177e4f7fd250976823944 (patch)
tree5ba9dcd2e54bc9abd1d333c3fb6c2e11842ff46f /sys/rpc
parent2b73aacaf9ab339d6aaaf256f17f298dc54c423e (diff)
downloadsrc-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.c5
-rw-r--r--sys/rpc/clnt_rc.c5
-rw-r--r--sys/rpc/clnt_vc.c9
-rw-r--r--sys/rpc/rpc_generic.c10
-rw-r--r--sys/rpc/svc_dg.c6
-rw-r--r--sys/rpc/svc_generic.c7
-rw-r--r--sys/rpc/svc_vc.c21
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) {
/*