Author: zec
Date: Fri Aug 28 19:12:44 2009
New Revision: 196622
URL: http://svn.freebsd.org/changeset/base/196622

Log:
  MFC r196503:
  
    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)
  
  Approved by:  re (rwatson)

Modified:
  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)
  stable/8/sys/dev/xen/xenpci/   (props changed)
  stable/8/sys/fs/nfsclient/nfs_clvnops.c
  stable/8/sys/nfsclient/nfs_vnops.c
  stable/8/sys/rpc/clnt_dg.c
  stable/8/sys/rpc/clnt_rc.c
  stable/8/sys/rpc/clnt_vc.c
  stable/8/sys/rpc/rpc_generic.c
  stable/8/sys/rpc/svc_dg.c
  stable/8/sys/rpc/svc_generic.c
  stable/8/sys/rpc/svc_vc.c

Modified: stable/8/sys/fs/nfsclient/nfs_clvnops.c
==============================================================================
--- stable/8/sys/fs/nfsclient/nfs_clvnops.c     Fri Aug 28 19:10:58 2009        
(r196621)
+++ stable/8/sys/fs/nfsclient/nfs_clvnops.c     Fri Aug 28 19:12:44 2009        
(r196622)
@@ -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: stable/8/sys/nfsclient/nfs_vnops.c
==============================================================================
--- stable/8/sys/nfsclient/nfs_vnops.c  Fri Aug 28 19:10:58 2009        
(r196621)
+++ stable/8/sys/nfsclient/nfs_vnops.c  Fri Aug 28 19:12:44 2009        
(r196622)
@@ -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: stable/8/sys/rpc/clnt_dg.c
==============================================================================
--- stable/8/sys/rpc/clnt_dg.c  Fri Aug 28 19:10:58 2009        (r196621)
+++ stable/8/sys/rpc/clnt_dg.c  Fri Aug 28 19:12:44 2009        (r196622)
@@ -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: stable/8/sys/rpc/clnt_rc.c
==============================================================================
--- stable/8/sys/rpc/clnt_rc.c  Fri Aug 28 19:10:58 2009        (r196621)
+++ stable/8/sys/rpc/clnt_rc.c  Fri Aug 28 19:12:44 2009        (r196622)
@@ -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: stable/8/sys/rpc/clnt_vc.c
==============================================================================
--- stable/8/sys/rpc/clnt_vc.c  Fri Aug 28 19:10:58 2009        (r196621)
+++ stable/8/sys/rpc/clnt_vc.c  Fri Aug 28 19:12:44 2009        (r196622)
@@ -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: stable/8/sys/rpc/rpc_generic.c
==============================================================================
--- stable/8/sys/rpc/rpc_generic.c      Fri Aug 28 19:10:58 2009        
(r196621)
+++ stable/8/sys/rpc/rpc_generic.c      Fri Aug 28 19:12:44 2009        
(r196622)
@@ -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: stable/8/sys/rpc/svc_dg.c
==============================================================================
--- stable/8/sys/rpc/svc_dg.c   Fri Aug 28 19:10:58 2009        (r196621)
+++ stable/8/sys/rpc/svc_dg.c   Fri Aug 28 19:12:44 2009        (r196622)
@@ -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: stable/8/sys/rpc/svc_generic.c
==============================================================================
--- stable/8/sys/rpc/svc_generic.c      Fri Aug 28 19:10:58 2009        
(r196621)
+++ stable/8/sys/rpc/svc_generic.c      Fri Aug 28 19:12:44 2009        
(r196622)
@@ -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: stable/8/sys/rpc/svc_vc.c
==============================================================================
--- stable/8/sys/rpc/svc_vc.c   Fri Aug 28 19:10:58 2009        (r196621)
+++ stable/8/sys/rpc/svc_vc.c   Fri Aug 28 19:12:44 2009        (r196622)
@@ -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) {
                        /*
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to