Signed-off-by: Matt Helsley <matthltc@xxxxxxxxxx>
---
fs/nfs/client.c | 5 ++++-
include/linux/net.h | 2 ++
include/linux/sunrpc/clnt.h | 1 +
include/linux/sunrpc/xprt.h | 1 +
net/socket.c | 5 +++++
net/sunrpc/clnt.c | 1 +
net/sunrpc/xprtsock.c | 26 ++++++++++++++++++++++----
7 files changed, 36 insertions(+), 5 deletions(-)
Index: linux-2.6.29/fs/nfs/client.c
===================================================================
--- linux-2.6.29.orig/fs/nfs/client.c
+++ linux-2.6.29/fs/nfs/client.c
@@ -10,11 +10,11 @@
*/
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/sched.h>
+#include <linux/nsproxy.h>
#include <linux/time.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/stat.h>
@@ -564,10 +564,11 @@ static int nfs_create_rpc_client(struct
struct rpc_clnt *clnt = NULL;
struct rpc_create_args args = {
.protocol = clp->cl_proto,
.address = (struct sockaddr *)&clp->cl_addr,
.addrsize = clp->cl_addrlen,
+ .net_ns = current->nsproxy->net_ns,
.timeout = timeparms,
.servername = clp->cl_hostname,
.program = &nfs_program,
.version = clp->rpc_ops->version,
.authflavor = flavor,
@@ -579,12 +580,14 @@ static int nfs_create_rpc_client(struct
args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
if (!IS_ERR(clp->cl_rpcclient))
return 0;
+ get_net(current->nsproxy->net_ns);
clnt = rpc_create(&args);
if (IS_ERR(clnt)) {
+ put_net(current->nsproxy->net_ns);
dprintk("%s: cannot create RPC client. Error = %ld\n",
__func__, PTR_ERR(clnt));
return PTR_ERR(clnt);
}
Index: linux-2.6.29/include/linux/net.h
===================================================================
--- linux-2.6.29.orig/include/linux/net.h
+++ linux-2.6.29/include/linux/net.h
@@ -210,10 +210,12 @@ extern int sock_register(const stru
extern void sock_unregister(int family);
extern int sock_create(int family, int type, int proto,
struct socket **res);
extern int sock_create_kern(int family, int type, int proto,
struct socket **res);
+extern int net_sock_create_kern(struct net *net, int family,
int type,
+ int proto, struct socket **res);
extern int sock_create_lite(int family, int type, int proto,
struct socket **res);
extern void sock_release(struct socket *sock);
extern int sock_sendmsg(struct socket *sock, struct msghdr
*msg,
size_t len);
Index: linux-2.6.29/include/linux/sunrpc/clnt.h
===================================================================
--- linux-2.6.29.orig/include/linux/sunrpc/clnt.h
+++ linux-2.6.29/include/linux/sunrpc/clnt.h
@@ -100,10 +100,11 @@ struct rpc_procinfo {
struct rpc_create_args {
int protocol;
struct sockaddr *address;
size_t addrsize;
struct sockaddr *saddress;
+ struct net *net_ns;
const struct rpc_timeout *timeout;
char *servername;
struct rpc_program *program;
u32 prognumber; /* overrides program->number */
u32 version;
Index: linux-2.6.29/include/linux/sunrpc/xprt.h
===================================================================
--- linux-2.6.29.orig/include/linux/sunrpc/xprt.h
+++ linux-2.6.29/include/linux/sunrpc/xprt.h
@@ -194,10 +194,11 @@ struct rpc_xprt {
struct xprt_create {
int ident; /* XPRT_TRANSPORT identifier */
struct sockaddr * srcaddr; /* optional local address */
struct sockaddr * dstaddr; /* remote peer address */
+ struct net * net_ns; /* net namespace */
size_t addrlen;
};
struct xprt_class {
struct list_head list;
Index: linux-2.6.29/net/socket.c
===================================================================
--- linux-2.6.29.orig/net/socket.c
+++ linux-2.6.29/net/socket.c
@@ -1212,10 +1212,15 @@ int sock_create(int family, int type, in
int sock_create_kern(int family, int type, int protocol, struct
socket **res)
{
return __sock_create(&init_net, family, type, protocol, res, 1);
}
+int net_sock_create_kern(struct net *net, int family, int type, int
protocol, struct socket **res)
+{
+ return __sock_create(net, family, type, protocol, res, 1);
+}
+
SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
{
int retval;
struct socket *sock;
int flags;
Index: linux-2.6.29/net/sunrpc/clnt.c
===================================================================
--- linux-2.6.29.orig/net/sunrpc/clnt.c
+++ linux-2.6.29/net/sunrpc/clnt.c
@@ -263,10 +263,11 @@ struct rpc_clnt *rpc_create(struct rpc_c
struct rpc_clnt *clnt;
struct xprt_create xprtargs = {
.ident = args->protocol,
.srcaddr = args->saddress,
.dstaddr = args->address,
+ .net_ns = args->net_ns,
.addrlen = args->addrsize,
};
char servername[48];
/*
Index: linux-2.6.29/net/sunrpc/xprtsock.c
===================================================================
--- linux-2.6.29.orig/net/sunrpc/xprtsock.c
+++ linux-2.6.29/net/sunrpc/xprtsock.c
@@ -234,10 +234,11 @@ struct sock_xprt {
* Connection of transports
*/
struct delayed_work connect_worker;
struct sockaddr_storage addr;
unsigned short port;
+ struct net *net_ns;
/*
* UDP socket buffer size parameters
*/
size_t rcvsize,
@@ -819,10 +820,11 @@ static void xs_destroy(struct rpc_xprt *
cancel_rearming_delayed_work(&transport->connect_worker);
xs_close(xprt);
xs_free_peer_addresses(xprt);
kfree(xprt->slot);
+ put_net(transport->net_ns);
kfree(xprt);
module_put(THIS_MODULE);
}
static inline struct rpc_xprt *xprt_from_sock(struct sock *sk)
@@ -1537,11 +1539,13 @@ static void xs_udp_connect_worker4(struc
goto out;
/* Start by resetting any existing state */
xs_close(xprt);
- if ((err = sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP,
&sock)) < 0) {
+ err = net_sock_create_kern(transport->net_ns, PF_INET, SOCK_DGRAM,
+ IPPROTO_UDP, &sock);
+ if (err < 0) {
dprintk("RPC: can't create UDP transport socket (%d).\n", -
err);
goto out;
}
xs_reclassify_socket4(sock);
@@ -1578,11 +1582,13 @@ static void xs_udp_connect_worker6(struc
goto out;
/* Start by resetting any existing state */
xs_close(xprt);
- if ((err = sock_create_kern(PF_INET6, SOCK_DGRAM, IPPROTO_UDP,
&sock)) < 0) {
+ err = net_sock_create_kern(transport->net_ns, PF_INET6, SOCK_DGRAM,
+ IPPROTO_UDP, &sock);
+ if (err < 0) {
dprintk("RPC: can't create UDP transport socket (%d).\n", -
err);
goto out;
}
xs_reclassify_socket6(sock);
@@ -1684,11 +1690,13 @@ static void xs_tcp_connect_worker4(struc
if (xprt->shutdown)
goto out;
if (!sock) {
/* start from scratch */
- if ((err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP,
&sock)) < 0) {
+ err = net_sock_create_kern(transport->net_ns, PF_INET,
+ SOCK_STREAM, IPPROTO_TCP, &sock);
+ if (err < 0) {
dprintk("RPC: can't create TCP transport socket (%d).\n", -
err);
goto out;
}
xs_reclassify_socket4(sock);
@@ -1744,11 +1752,13 @@ static void xs_tcp_connect_worker6(struc
if (xprt->shutdown)
goto out;
if (!sock) {
/* start from scratch */
- if ((err = sock_create_kern(PF_INET6, SOCK_STREAM, IPPROTO_TCP,
&sock)) < 0) {
+ err = net_sock_create_kern(transport->net_ns, PF_INET6,
+ SOCK_STREAM, IPPROTO_TCP, &sock);
+ if (err < 0) {
dprintk("RPC: can't create TCP transport socket (%d).\n", -
err);
goto out;
}
xs_reclassify_socket6(sock);
@@ -1988,10 +1998,14 @@ static struct rpc_xprt *xs_setup_udp(str
xprt->ops = &xs_udp_ops;
xprt->timeout = &xs_udp_default_timeout;
+ if (args->net_ns)
+ transport->net_ns = args->net_ns;
+ else
+ transport->net_ns = &init_net;
switch (addr->sa_family) {
case AF_INET:
if (((struct sockaddr_in *)addr)->sin_port != htons(0))
xprt_set_bound(xprt);
@@ -2055,10 +2069,14 @@ static struct rpc_xprt *xs_setup_tcp(str
xprt->idle_timeout = XS_IDLE_DISC_TO;
xprt->ops = &xs_tcp_ops;
xprt->timeout = &xs_tcp_default_timeout;
+ if (args->net_ns)
+ transport->net_ns = args->net_ns;
+ else
+ transport->net_ns = &init_net;
switch (addr->sa_family) {
case AF_INET:
if (((struct sockaddr_in *)addr)->sin_port != htons(0))
xprt_set_bound(xprt);