2010-09-27 10:05:57

by Pavel Emelyanov

[permalink] [raw]
Subject: [PATCH 0/8] sunrpc: Create sockets in namespaces

Hi!

This set implements pulling the net * argument down to the existing
sock_create_kern calls in the sunrpc layer and creating the sockets
in the given net.

Patch #7 opens the __sock_create for public and I hope we can do it
not in the Dave's tree :)

Applies to git://linux-nfs.org/~bfields/linux.git nfsd-next after the
ip_map_cache virtualization patch set I sent before.

Thanks,
Pavel


2010-09-27 10:06:36

by Pavel Emelyanov

[permalink] [raw]
Subject: [PATCH 1/8] sunrpc: Factor out rpc_xprt freeing


Signed-off-by: Pavel Emelyanov <[email protected]>
---
net/sunrpc/xprtsock.c | 20 ++++++++++++--------
1 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index b6309db..98d4b7b 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -759,6 +759,8 @@ static void xs_tcp_close(struct rpc_xprt *xprt)
xs_tcp_shutdown(xprt);
}

+static void xs_free_xprt(struct rpc_xprt *xprt);
+
/**
* xs_destroy - prepare to shutdown a transport
* @xprt: doomed transport
@@ -774,8 +776,7 @@ static void xs_destroy(struct rpc_xprt *xprt)

xs_close(xprt);
xs_free_peer_addresses(xprt);
- kfree(xprt->slot);
- kfree(xprt);
+ xs_free_xprt(xprt);
module_put(THIS_MODULE);
}

@@ -2298,6 +2299,12 @@ static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args,
return xprt;
}

+static void xs_free_xprt(struct rpc_xprt *xprt)
+{
+ kfree(xprt->slot);
+ kfree(xprt);
+}
+
static const struct rpc_timeout xs_udp_default_timeout = {
.to_initval = 5 * HZ,
.to_maxval = 30 * HZ,
@@ -2371,8 +2378,7 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args)
return xprt;
ret = ERR_PTR(-EINVAL);
out_err:
- kfree(xprt->slot);
- kfree(xprt);
+ xs_free_xprt(xprt);
return ret;
}

@@ -2447,8 +2453,7 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args)
return xprt;
ret = ERR_PTR(-EINVAL);
out_err:
- kfree(xprt->slot);
- kfree(xprt);
+ xs_free_xprt(xprt);
return ret;
}

@@ -2528,8 +2533,7 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args)
return xprt;
ret = ERR_PTR(-EINVAL);
out_err:
- kfree(xprt->slot);
- kfree(xprt);
+ xs_free_xprt(xprt);
return ret;
}

--
1.5.5.6


2010-09-27 19:40:46

by Chuck Lever III

[permalink] [raw]
Subject: Re: [PATCH 1/8] sunrpc: Factor out rpc_xprt freeing


On Sep 27, 2010, at 6:06 AM, Pavel Emelyanov wrote:

>
> Signed-off-by: Pavel Emelyanov <[email protected]>
> ---
> net/sunrpc/xprtsock.c | 20 ++++++++++++--------
> 1 files changed, 12 insertions(+), 8 deletions(-)
>
> diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
> index b6309db..98d4b7b 100644
> --- a/net/sunrpc/xprtsock.c
> +++ b/net/sunrpc/xprtsock.c
> @@ -759,6 +759,8 @@ static void xs_tcp_close(struct rpc_xprt *xprt)
> xs_tcp_shutdown(xprt);
> }
>
> +static void xs_free_xprt(struct rpc_xprt *xprt);

Style nit: we usually like forward declarations at the top of source files.

Do you need to fix up xprtrdma too? (eg. xprt_rdma_destroy) It looks like it has similar logic around freeing xprts. Even though it doesn't use sockets, do we need to be concerned about net namespaces for RDMA transports?

> +
> /**
> * xs_destroy - prepare to shutdown a transport
> * @xprt: doomed transport
> @@ -774,8 +776,7 @@ static void xs_destroy(struct rpc_xprt *xprt)
>
> xs_close(xprt);
> xs_free_peer_addresses(xprt);
> - kfree(xprt->slot);
> - kfree(xprt);
> + xs_free_xprt(xprt);
> module_put(THIS_MODULE);
> }
>
> @@ -2298,6 +2299,12 @@ static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args,
> return xprt;
> }
>
> +static void xs_free_xprt(struct rpc_xprt *xprt)
> +{
> + kfree(xprt->slot);
> + kfree(xprt);
> +}
> +
> static const struct rpc_timeout xs_udp_default_timeout = {
> .to_initval = 5 * HZ,
> .to_maxval = 30 * HZ,
> @@ -2371,8 +2378,7 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args)
> return xprt;
> ret = ERR_PTR(-EINVAL);
> out_err:
> - kfree(xprt->slot);
> - kfree(xprt);
> + xs_free_xprt(xprt);
> return ret;
> }
>
> @@ -2447,8 +2453,7 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args)
> return xprt;
> ret = ERR_PTR(-EINVAL);
> out_err:
> - kfree(xprt->slot);
> - kfree(xprt);
> + xs_free_xprt(xprt);
> return ret;
> }
>
> @@ -2528,8 +2533,7 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args)
> return xprt;
> ret = ERR_PTR(-EINVAL);
> out_err:
> - kfree(xprt->slot);
> - kfree(xprt);
> + xs_free_xprt(xprt);
> return ret;
> }
>
> --
> 1.5.5.6
>

--
chuck[dot]lever[at]oracle[dot]com





2010-09-27 10:08:37

by Pavel Emelyanov

[permalink] [raw]
Subject: [PATCH 5/8] sunrpc: Add net to xprt_create


Signed-off-by: Pavel Emelyanov <[email protected]>
---
include/linux/sunrpc/xprt.h | 1 +
net/sunrpc/clnt.c | 1 +
2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index ff5a77b..cd27538 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -249,6 +249,7 @@ static inline int bc_prealloc(struct rpc_rqst *req)

struct xprt_create {
int ident; /* XPRT_TRANSPORT identifier */
+ struct net * net;
struct sockaddr * srcaddr; /* optional local address */
struct sockaddr * dstaddr; /* remote peer address */
size_t addrlen;
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index fa55490..f4bbd83 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -284,6 +284,7 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
struct rpc_xprt *xprt;
struct rpc_clnt *clnt;
struct xprt_create xprtargs = {
+ .net = args->net,
.ident = args->protocol,
.srcaddr = args->saddress,
.dstaddr = args->address,
--
1.5.5.6


2010-09-27 13:41:41

by Pavel Emelyanov

[permalink] [raw]
Subject: Re: [PATCH 7/8] net: Export __sock_create

On 09/27/2010 05:31 PM, Trond Myklebust wrote:
> On Mon, 2010-09-27 at 14:09 +0400, Pavel Emelyanov wrote:
>> Can we can do it not through the Dave's tree?
>
> I think we will still need Dave's approval for this. Either an Ack or a
> signed-off-by. Linus will very likely yell at us and refuse to take the
> patch if we don't.

OK, I then put Dave in Cc.

And a small background of the patch - I'm trying to make sunrpc layer work
in net namespaces and in order to do this I need to turn existing calls to
sock_create_kern() into __sock_create() to specify the net namespace the
socket are to be created in.

Dave, can we go on with this, please? :)

> Cheers
> Trond
>
>> Signed-off-by: Pavel Emelyanov <[email protected]>
>> ---
>> include/linux/net.h | 2 ++
>> net/socket.c | 3 ++-
>> 2 files changed, 4 insertions(+), 1 deletions(-)
>>
>> diff --git a/include/linux/net.h b/include/linux/net.h
>> index dee0b11..16faa13 100644
>> --- a/include/linux/net.h
>> +++ b/include/linux/net.h
>> @@ -229,6 +229,8 @@ enum {
>> extern int sock_wake_async(struct socket *sk, int how, int band);
>> extern int sock_register(const struct net_proto_family *fam);
>> extern void sock_unregister(int family);
>> +extern int __sock_create(struct net *net, int family, int type, int proto,
>> + struct socket **res, int kern);
>> extern int sock_create(int family, int type, int proto,
>> struct socket **res);
>> extern int sock_create_kern(int family, int type, int proto,
>> diff --git a/net/socket.c b/net/socket.c
>> index 2270b94..0c37b00 100644
>> --- a/net/socket.c
>> +++ b/net/socket.c
>> @@ -1144,7 +1144,7 @@ call_kill:
>> }
>> EXPORT_SYMBOL(sock_wake_async);
>>
>> -static int __sock_create(struct net *net, int family, int type, int protocol,
>> +int __sock_create(struct net *net, int family, int type, int protocol,
>> struct socket **res, int kern)
>> {
>> int err;
>> @@ -1256,6 +1256,7 @@ out_release:
>> rcu_read_unlock();
>> goto out_sock_release;
>> }
>> +EXPORT_SYMBOL(__sock_create);
>>
>> int sock_create(int family, int type, int protocol, struct socket **res)
>> {

2010-09-27 10:08:09

by Pavel Emelyanov

[permalink] [raw]
Subject: [PATCH 4/8] sunrpc: Add net to rpc_create_args


Signed-off-by: Pavel Emelyanov <[email protected]>
---
fs/lockd/host.c | 1 +
fs/lockd/mon.c | 1 +
fs/nfs/client.c | 1 +
fs/nfs/mount_clnt.c | 2 ++
fs/nfsd/nfs4callback.c | 1 +
include/linux/sunrpc/clnt.h | 1 +
net/sunrpc/rpcb_clnt.c | 2 ++
7 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index bb464d1..25e21e4 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -353,6 +353,7 @@ nlm_bind_host(struct nlm_host *host)
.to_retries = 5U,
};
struct rpc_create_args args = {
+ .net = &init_net,
.protocol = host->h_proto,
.address = nlm_addr(host),
.addrsize = host->h_addrlen,
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index e301546..e0c9189 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -69,6 +69,7 @@ static struct rpc_clnt *nsm_create(void)
.sin_addr.s_addr = htonl(INADDR_LOOPBACK),
};
struct rpc_create_args args = {
+ .net = &init_net,
.protocol = XPRT_TRANSPORT_UDP,
.address = (struct sockaddr *)&sin,
.addrsize = sizeof(sin),
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index e734072..351b711 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -601,6 +601,7 @@ static int nfs_create_rpc_client(struct nfs_client *clp,
{
struct rpc_clnt *clnt = NULL;
struct rpc_create_args args = {
+ .net = &init_net,
.protocol = clp->cl_proto,
.address = (struct sockaddr *)&clp->cl_addr,
.addrsize = clp->cl_addrlen,
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
index 59047f8..4b47203 100644
--- a/fs/nfs/mount_clnt.c
+++ b/fs/nfs/mount_clnt.c
@@ -153,6 +153,7 @@ int nfs_mount(struct nfs_mount_request *info)
.rpc_resp = &result,
};
struct rpc_create_args args = {
+ .net = &init_net,
.protocol = info->protocol,
.address = info->sap,
.addrsize = info->salen,
@@ -224,6 +225,7 @@ void nfs_umount(const struct nfs_mount_request *info)
.to_retries = 2,
};
struct rpc_create_args args = {
+ .net = &init_net,
.protocol = IPPROTO_UDP,
.address = info->sap,
.addrsize = info->salen,
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 014482c..1112f45 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -479,6 +479,7 @@ int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *cb)
.to_retries = 0,
};
struct rpc_create_args args = {
+ .net = &init_net,
.protocol = XPRT_TRANSPORT_TCP,
.address = (struct sockaddr *) &cb->cb_addr,
.addrsize = cb->cb_addrlen,
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index 85f38a6..58c4473 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -102,6 +102,7 @@ struct rpc_procinfo {
#ifdef __KERNEL__

struct rpc_create_args {
+ struct net *net;
int protocol;
struct sockaddr *address;
size_t addrsize;
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index dac219a..83af38d 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -177,6 +177,7 @@ static DEFINE_MUTEX(rpcb_create_local_mutex);
static int rpcb_create_local(void)
{
struct rpc_create_args args = {
+ .net = &init_net,
.protocol = XPRT_TRANSPORT_TCP,
.address = (struct sockaddr *)&rpcb_inaddr_loopback,
.addrsize = sizeof(rpcb_inaddr_loopback),
@@ -228,6 +229,7 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
size_t salen, int proto, u32 version)
{
struct rpc_create_args args = {
+ .net = &init_net,
.protocol = proto,
.address = srvaddr,
.addrsize = salen,
--
1.5.5.6


2010-09-28 17:40:27

by David Miller

[permalink] [raw]
Subject: Re: [PATCH 7/8] net: Export __sock_create

From: Pavel Emelyanov <[email protected]>
Date: Mon, 27 Sep 2010 17:41:23 +0400

> On 09/27/2010 05:31 PM, Trond Myklebust wrote:
>> On Mon, 2010-09-27 at 14:09 +0400, Pavel Emelyanov wrote:
>>> Can we can do it not through the Dave's tree?
>>
>> I think we will still need Dave's approval for this. Either an Ack or a
>> signed-off-by. Linus will very likely yell at us and refuse to take the
>> patch if we don't.
>
> OK, I then put Dave in Cc.
>
> And a small background of the patch - I'm trying to make sunrpc layer work
> in net namespaces and in order to do this I need to turn existing calls to
> sock_create_kern() into __sock_create() to specify the net namespace the
> socket are to be created in.
>
> Dave, can we go on with this, please? :)

This is fine:

Acked-by: David S. Miller <[email protected]>

2010-09-28 13:59:46

by Myklebust, Trond

[permalink] [raw]
Subject: Re: [PATCH 1/8] sunrpc: Factor out rpc_xprt freeing

On Tue, 2010-09-28 at 14:44 +0400, Pavel Emelyanov wrote:
> On 09/27/2010 11:40 PM, Chuck Lever wrote:
> >
> > On Sep 27, 2010, at 6:06 AM, Pavel Emelyanov wrote:
> >
> >>
> >> Signed-off-by: Pavel Emelyanov <[email protected]>
> >> ---
> >> net/sunrpc/xprtsock.c | 20 ++++++++++++--------
> >> 1 files changed, 12 insertions(+), 8 deletions(-)
> >>
> >> diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
> >> index b6309db..98d4b7b 100644
> >> --- a/net/sunrpc/xprtsock.c
> >> +++ b/net/sunrpc/xprtsock.c
> >> @@ -759,6 +759,8 @@ static void xs_tcp_close(struct rpc_xprt *xprt)
> >> xs_tcp_shutdown(xprt);
> >> }
> >>
> >> +static void xs_free_xprt(struct rpc_xprt *xprt);
> >
> > Style nit: we usually like forward declarations at the top of source files.
>
> OK.
>
> > Do you need to fix up xprtrdma too? (eg. xprt_rdma_destroy) It looks like it has
> > similar logic around freeing xprts.
>
> Indeed. Bruce, which way would you prefer - should I re-send the whole set or
> can apply this change incrementally?
>
> > Even though it doesn't use sockets, do we need to be concerned about net namespaces
> > for RDMA transports?
>
> I believe we should, since at least its initialization goes to the rdma_resolve_addr
> which in turn resolves the address using IP-level routing. But I wanted to finish with
> the tcp/udp transports first.

If you are redoing the patch, then could you please just get rid of the
above forward declaration for xs_free_xprt, and instead just move the
function itself further up the file?

Cheers
Trond

2010-09-28 10:45:45

by Pavel Emelyanov

[permalink] [raw]
Subject: Re: [PATCH 1/8] sunrpc: Factor out rpc_xprt freeing

On 09/27/2010 11:40 PM, Chuck Lever wrote:
>
> On Sep 27, 2010, at 6:06 AM, Pavel Emelyanov wrote:
>
>>
>> Signed-off-by: Pavel Emelyanov <[email protected]>
>> ---
>> net/sunrpc/xprtsock.c | 20 ++++++++++++--------
>> 1 files changed, 12 insertions(+), 8 deletions(-)
>>
>> diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
>> index b6309db..98d4b7b 100644
>> --- a/net/sunrpc/xprtsock.c
>> +++ b/net/sunrpc/xprtsock.c
>> @@ -759,6 +759,8 @@ static void xs_tcp_close(struct rpc_xprt *xprt)
>> xs_tcp_shutdown(xprt);
>> }
>>
>> +static void xs_free_xprt(struct rpc_xprt *xprt);
>
> Style nit: we usually like forward declarations at the top of source files.

OK.

> Do you need to fix up xprtrdma too? (eg. xprt_rdma_destroy) It looks like it has
> similar logic around freeing xprts.

Indeed. Bruce, which way would you prefer - should I re-send the whole set or
can apply this change incrementally?

> Even though it doesn't use sockets, do we need to be concerned about net namespaces
> for RDMA transports?

I believe we should, since at least its initialization goes to the rdma_resolve_addr
which in turn resolves the address using IP-level routing. But I wanted to finish with
the tcp/udp transports first.

Thanks,
Pavel

2010-09-27 13:31:21

by Myklebust, Trond

[permalink] [raw]
Subject: Re: [PATCH 7/8] net: Export __sock_create

On Mon, 2010-09-27 at 14:09 +0400, Pavel Emelyanov wrote:
> Can we can do it not through the Dave's tree?

I think we will still need Dave's approval for this. Either an Ack or a
signed-off-by. Linus will very likely yell at us and refuse to take the
patch if we don't.

Cheers
Trond

> Signed-off-by: Pavel Emelyanov <[email protected]>
> ---
> include/linux/net.h | 2 ++
> net/socket.c | 3 ++-
> 2 files changed, 4 insertions(+), 1 deletions(-)
>
> diff --git a/include/linux/net.h b/include/linux/net.h
> index dee0b11..16faa13 100644
> --- a/include/linux/net.h
> +++ b/include/linux/net.h
> @@ -229,6 +229,8 @@ enum {
> extern int sock_wake_async(struct socket *sk, int how, int band);
> extern int sock_register(const struct net_proto_family *fam);
> extern void sock_unregister(int family);
> +extern int __sock_create(struct net *net, int family, int type, int proto,
> + struct socket **res, int kern);
> extern int sock_create(int family, int type, int proto,
> struct socket **res);
> extern int sock_create_kern(int family, int type, int proto,
> diff --git a/net/socket.c b/net/socket.c
> index 2270b94..0c37b00 100644
> --- a/net/socket.c
> +++ b/net/socket.c
> @@ -1144,7 +1144,7 @@ call_kill:
> }
> EXPORT_SYMBOL(sock_wake_async);
>
> -static int __sock_create(struct net *net, int family, int type, int protocol,
> +int __sock_create(struct net *net, int family, int type, int protocol,
> struct socket **res, int kern)
> {
> int err;
> @@ -1256,6 +1256,7 @@ out_release:
> rcu_read_unlock();
> goto out_sock_release;
> }
> +EXPORT_SYMBOL(__sock_create);
>
> int sock_create(int family, int type, int protocol, struct socket **res)
> {



2010-09-27 10:07:42

by Pavel Emelyanov

[permalink] [raw]
Subject: [PATCH 3/8] sunrpc: Pull net argument downto svc_create_socket

After this the socket creation in it knows the context.

Signed-off-by: Pavel Emelyanov <[email protected]>
---
include/linux/sunrpc/svc_xprt.h | 1 +
net/sunrpc/svc_xprt.c | 5 +++--
net/sunrpc/svcsock.c | 10 +++++++---
net/sunrpc/xprtrdma/svc_rdma_transport.c | 2 ++
4 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
index 646263c..bb18297 100644
--- a/include/linux/sunrpc/svc_xprt.h
+++ b/include/linux/sunrpc/svc_xprt.h
@@ -12,6 +12,7 @@

struct svc_xprt_ops {
struct svc_xprt *(*xpo_create)(struct svc_serv *,
+ struct net *net,
struct sockaddr *, int,
int);
struct svc_xprt *(*xpo_accept)(struct svc_xprt *);
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index d80789a..678b6ee 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -166,6 +166,7 @@ EXPORT_SYMBOL_GPL(svc_xprt_init);

static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl,
struct svc_serv *serv,
+ struct net *net,
const int family,
const unsigned short port,
int flags)
@@ -200,7 +201,7 @@ static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl,
return ERR_PTR(-EAFNOSUPPORT);
}

- return xcl->xcl_ops->xpo_create(serv, sap, len, flags);
+ return xcl->xcl_ops->xpo_create(serv, net, sap, len, flags);
}

int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
@@ -221,7 +222,7 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
goto err;

spin_unlock(&svc_xprt_class_lock);
- newxprt = __svc_xpo_create(xcl, serv, family, port, flags);
+ newxprt = __svc_xpo_create(xcl, serv, net, family, port, flags);
if (IS_ERR(newxprt)) {
module_put(xcl->xcl_owner);
return PTR_ERR(newxprt);
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 7e534dd..5593385 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -64,7 +64,8 @@ static void svc_tcp_sock_detach(struct svc_xprt *);
static void svc_sock_free(struct svc_xprt *);

static struct svc_xprt *svc_create_socket(struct svc_serv *, int,
- struct sockaddr *, int, int);
+ struct net *, struct sockaddr *,
+ int, int);
#ifdef CONFIG_DEBUG_LOCK_ALLOC
static struct lock_class_key svc_key[2];
static struct lock_class_key svc_slock_key[2];
@@ -657,10 +658,11 @@ static struct svc_xprt *svc_udp_accept(struct svc_xprt *xprt)
}

static struct svc_xprt *svc_udp_create(struct svc_serv *serv,
+ struct net *net,
struct sockaddr *sa, int salen,
int flags)
{
- return svc_create_socket(serv, IPPROTO_UDP, sa, salen, flags);
+ return svc_create_socket(serv, IPPROTO_UDP, net, sa, salen, flags);
}

static struct svc_xprt_ops svc_udp_ops = {
@@ -1178,10 +1180,11 @@ static int svc_tcp_has_wspace(struct svc_xprt *xprt)
}

static struct svc_xprt *svc_tcp_create(struct svc_serv *serv,
+ struct net *net,
struct sockaddr *sa, int salen,
int flags)
{
- return svc_create_socket(serv, IPPROTO_TCP, sa, salen, flags);
+ return svc_create_socket(serv, IPPROTO_TCP, net, sa, salen, flags);
}

static struct svc_xprt_ops svc_tcp_ops = {
@@ -1385,6 +1388,7 @@ EXPORT_SYMBOL_GPL(svc_addsock);
*/
static struct svc_xprt *svc_create_socket(struct svc_serv *serv,
int protocol,
+ struct net *net,
struct sockaddr *sin, int len,
int flags)
{
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
index edea15a..950a206 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
@@ -52,6 +52,7 @@
#define RPCDBG_FACILITY RPCDBG_SVCXPRT

static struct svc_xprt *svc_rdma_create(struct svc_serv *serv,
+ struct net *net,
struct sockaddr *sa, int salen,
int flags);
static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt);
@@ -670,6 +671,7 @@ static int rdma_cma_handler(struct rdma_cm_id *cma_id,
* Create a listening RDMA service endpoint.
*/
static struct svc_xprt *svc_rdma_create(struct svc_serv *serv,
+ struct net *net,
struct sockaddr *sa, int salen,
int flags)
{
--
1.5.5.6


2010-09-27 10:09:49

by Pavel Emelyanov

[permalink] [raw]
Subject: [PATCH 7/8] net: Export __sock_create

Can we can do it not through the Dave's tree?

Signed-off-by: Pavel Emelyanov <[email protected]>
---
include/linux/net.h | 2 ++
net/socket.c | 3 ++-
2 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/include/linux/net.h b/include/linux/net.h
index dee0b11..16faa13 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -229,6 +229,8 @@ enum {
extern int sock_wake_async(struct socket *sk, int how, int band);
extern int sock_register(const struct net_proto_family *fam);
extern void sock_unregister(int family);
+extern int __sock_create(struct net *net, int family, int type, int proto,
+ struct socket **res, int kern);
extern int sock_create(int family, int type, int proto,
struct socket **res);
extern int sock_create_kern(int family, int type, int proto,
diff --git a/net/socket.c b/net/socket.c
index 2270b94..0c37b00 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1144,7 +1144,7 @@ call_kill:
}
EXPORT_SYMBOL(sock_wake_async);

-static int __sock_create(struct net *net, int family, int type, int protocol,
+int __sock_create(struct net *net, int family, int type, int protocol,
struct socket **res, int kern)
{
int err;
@@ -1256,6 +1256,7 @@ out_release:
rcu_read_unlock();
goto out_sock_release;
}
+EXPORT_SYMBOL(__sock_create);

int sock_create(int family, int type, int protocol, struct socket **res)
{
--
1.5.5.6


2010-09-27 10:07:09

by Pavel Emelyanov

[permalink] [raw]
Subject: [PATCH 2/8] sunrpc: Add net argument to svc_create_xprt


Signed-off-by: Pavel Emelyanov <[email protected]>
---
fs/lockd/svc.c | 2 +-
fs/nfs/callback.c | 4 ++--
fs/nfsd/nfsctl.c | 4 ++--
fs/nfsd/nfssvc.c | 5 +++--
include/linux/sunrpc/svc_xprt.h | 4 ++--
net/sunrpc/svc_xprt.c | 4 ++--
6 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index f1bacf1..b13aabc 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -206,7 +206,7 @@ static int create_lockd_listener(struct svc_serv *serv, const char *name,

xprt = svc_find_xprt(serv, name, family, 0);
if (xprt == NULL)
- return svc_create_xprt(serv, name, family, port,
+ return svc_create_xprt(serv, name, &init_net, family, port,
SVC_SOCK_DEFAULTS);
svc_xprt_put(xprt);
return 0;
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index e17b49e..aeec017 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -109,7 +109,7 @@ nfs4_callback_up(struct svc_serv *serv)
{
int ret;

- ret = svc_create_xprt(serv, "tcp", PF_INET,
+ ret = svc_create_xprt(serv, "tcp", &init_net, PF_INET,
nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS);
if (ret <= 0)
goto out_err;
@@ -117,7 +117,7 @@ nfs4_callback_up(struct svc_serv *serv)
dprintk("NFS: Callback listener port = %u (af %u)\n",
nfs_callback_tcpport, PF_INET);

- ret = svc_create_xprt(serv, "tcp", PF_INET6,
+ ret = svc_create_xprt(serv, "tcp", &init_net, PF_INET6,
nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS);
if (ret > 0) {
nfs_callback_tcpport6 = ret;
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index b6e192d..b81da24 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -1015,12 +1015,12 @@ static ssize_t __write_ports_addxprt(char *buf)
if (err != 0)
return err;

- err = svc_create_xprt(nfsd_serv, transport,
+ err = svc_create_xprt(nfsd_serv, transport, &init_net,
PF_INET, port, SVC_SOCK_ANONYMOUS);
if (err < 0)
goto out_err;

- err = svc_create_xprt(nfsd_serv, transport,
+ err = svc_create_xprt(nfsd_serv, transport, &init_net,
PF_INET6, port, SVC_SOCK_ANONYMOUS);
if (err < 0 && err != -EAFNOSUPPORT)
goto out_close;
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index e2c4346..2bae1d8 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -16,6 +16,7 @@
#include <linux/lockd/bind.h>
#include <linux/nfsacl.h>
#include <linux/seq_file.h>
+#include <net/net_namespace.h>
#include "nfsd.h"
#include "cache.h"
#include "vfs.h"
@@ -186,12 +187,12 @@ static int nfsd_init_socks(int port)
if (!list_empty(&nfsd_serv->sv_permsocks))
return 0;

- error = svc_create_xprt(nfsd_serv, "udp", PF_INET, port,
+ error = svc_create_xprt(nfsd_serv, "udp", &init_net, PF_INET, port,
SVC_SOCK_DEFAULTS);
if (error < 0)
return error;

- error = svc_create_xprt(nfsd_serv, "tcp", PF_INET, port,
+ error = svc_create_xprt(nfsd_serv, "tcp", &init_net, PF_INET, port,
SVC_SOCK_DEFAULTS);
if (error < 0)
return error;
diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
index e50e3ec..646263c 100644
--- a/include/linux/sunrpc/svc_xprt.h
+++ b/include/linux/sunrpc/svc_xprt.h
@@ -74,8 +74,8 @@ int svc_reg_xprt_class(struct svc_xprt_class *);
void svc_unreg_xprt_class(struct svc_xprt_class *);
void svc_xprt_init(struct svc_xprt_class *, struct svc_xprt *,
struct svc_serv *);
-int svc_create_xprt(struct svc_serv *, const char *, const int,
- const unsigned short, int);
+int svc_create_xprt(struct svc_serv *, const char *, struct net *,
+ const int, const unsigned short, int);
void svc_xprt_enqueue(struct svc_xprt *xprt);
void svc_xprt_received(struct svc_xprt *);
void svc_xprt_put(struct svc_xprt *xprt);
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index f7e8915..d80789a 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -204,8 +204,8 @@ static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl,
}

int svc_create_xprt(struct svc_serv *serv, const char *xprt_name,
- const int family, const unsigned short port,
- int flags)
+ struct net *net, const int family,
+ const unsigned short port, int flags)
{
struct svc_xprt_class *xcl;

--
1.5.5.6


2010-09-27 10:10:15

by Pavel Emelyanov

[permalink] [raw]
Subject: [PATCH 8/8] sunrpc: Create sockets in net namespaces

The context is already known in all the sock_create callers.

Signed-off-by: Pavel Emelyanov <[email protected]>
---
net/sunrpc/svcsock.c | 2 +-
net/sunrpc/xprtsock.c | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 5593385..88de3d0 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -1425,7 +1425,7 @@ static struct svc_xprt *svc_create_socket(struct svc_serv *serv,
return ERR_PTR(-EINVAL);
}

- error = sock_create_kern(family, type, protocol, &sock);
+ error = __sock_create(net, family, type, protocol, &sock, 1);
if (error < 0)
return ERR_PTR(error);

diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 292f449..aa24ba5 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -1682,7 +1682,7 @@ static void xs_udp_connect_worker4(struct work_struct *work)
/* Start by resetting any existing state */
xs_reset_transport(transport);

- err = sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock);
+ err = __sock_create(xprt->xprt_net, PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock, 1);
if (err < 0) {
dprintk("RPC: can't create UDP transport socket (%d).\n", -err);
goto out;
@@ -1727,7 +1727,7 @@ static void xs_udp_connect_worker6(struct work_struct *work)
/* Start by resetting any existing state */
xs_reset_transport(transport);

- err = sock_create_kern(PF_INET6, SOCK_DGRAM, IPPROTO_UDP, &sock);
+ err = __sock_create(xprt->xprt_net, PF_INET6, SOCK_DGRAM, IPPROTO_UDP, &sock, 1);
if (err < 0) {
dprintk("RPC: can't create UDP transport socket (%d).\n", -err);
goto out;
@@ -1933,7 +1933,7 @@ static struct socket *xs_create_tcp_sock4(struct rpc_xprt *xprt,
int err;

/* start from scratch */
- err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
+ err = __sock_create(xprt->xprt_net, PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock, 1);
if (err < 0) {
dprintk("RPC: can't create TCP transport socket (%d).\n",
-err);
@@ -1972,7 +1972,7 @@ static struct socket *xs_create_tcp_sock6(struct rpc_xprt *xprt,
int err;

/* start from scratch */
- err = sock_create_kern(PF_INET6, SOCK_STREAM, IPPROTO_TCP, &sock);
+ err = __sock_create(xprt->xprt_net, PF_INET6, SOCK_STREAM, IPPROTO_TCP, &sock, 1);
if (err < 0) {
dprintk("RPC: can't create TCP transport socket (%d).\n",
-err);
--
1.5.5.6


2010-09-28 13:56:43

by J. Bruce Fields

[permalink] [raw]
Subject: Re: [PATCH 1/8] sunrpc: Factor out rpc_xprt freeing

On Tue, Sep 28, 2010 at 02:44:45PM +0400, Pavel Emelyanov wrote:
> On 09/27/2010 11:40 PM, Chuck Lever wrote:
> >
> > On Sep 27, 2010, at 6:06 AM, Pavel Emelyanov wrote:
> >
> >>
> >> Signed-off-by: Pavel Emelyanov <[email protected]>
> >> ---
> >> net/sunrpc/xprtsock.c | 20 ++++++++++++--------
> >> 1 files changed, 12 insertions(+), 8 deletions(-)
> >>
> >> diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
> >> index b6309db..98d4b7b 100644
> >> --- a/net/sunrpc/xprtsock.c
> >> +++ b/net/sunrpc/xprtsock.c
> >> @@ -759,6 +759,8 @@ static void xs_tcp_close(struct rpc_xprt *xprt)
> >> xs_tcp_shutdown(xprt);
> >> }
> >>
> >> +static void xs_free_xprt(struct rpc_xprt *xprt);
> >
> > Style nit: we usually like forward declarations at the top of source files.
>
> OK.
>
> > Do you need to fix up xprtrdma too? (eg. xprt_rdma_destroy) It looks like it has
> > similar logic around freeing xprts.
>
> Indeed. Bruce, which way would you prefer - should I re-send the whole set or
> can apply this change incrementally?

I haven't pushed it out yet, so just do whichever you prefer.

--b.

>
> > Even though it doesn't use sockets, do we need to be concerned about net namespaces
> > for RDMA transports?
>
> I believe we should, since at least its initialization goes to the rdma_resolve_addr
> which in turn resolves the address using IP-level routing. But I wanted to finish with
> the tcp/udp transports first.
>
> Thanks,
> Pavel

2010-09-27 10:09:21

by Pavel Emelyanov

[permalink] [raw]
Subject: [PATCH 6/8] sunrpc: Tag rpc_xprt with net

The net is known from the xprt_create and this tagging will also
give us the context in the connection workers where real sockets
are created.

Signed-off-by: Pavel Emelyanov <[email protected]>
---
include/linux/sunrpc/xprt.h | 1 +
net/sunrpc/xprtsock.c | 2 ++
2 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index cd27538..83ae00a 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -224,6 +224,7 @@ struct rpc_xprt {
bklog_u; /* backlog queue utilization */
} stat;

+ struct net *xprt_net;
const char *address_strings[RPC_DISPLAY_MAX];
};

diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 98d4b7b..292f449 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -2296,11 +2296,13 @@ static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args,
if (args->srcaddr)
memcpy(&new->srcaddr, args->srcaddr, args->addrlen);

+ xprt->xprt_net = get_net(args->net);
return xprt;
}

static void xs_free_xprt(struct rpc_xprt *xprt)
{
+ put_net(xprt->xprt_net);
kfree(xprt->slot);
kfree(xprt);
}
--
1.5.5.6


2010-09-27 19:10:08

by J. Bruce Fields

[permalink] [raw]
Subject: Re: [PATCH 0/8] sunrpc: Create sockets in namespaces

On Mon, Sep 27, 2010 at 02:05:46PM +0400, Pavel Emelyanov wrote:
> Hi!
>
> This set implements pulling the net * argument down to the existing
> sock_create_kern calls in the sunrpc layer and creating the sockets
> in the given net.
>
> Patch #7 opens the __sock_create for public and I hope we can do it
> not in the Dave's tree :)
>
> Applies to git://linux-nfs.org/~bfields/linux.git nfsd-next after the
> ip_map_cache virtualization patch set I sent before.

They look fine to me.

--b.

2010-09-28 14:23:57

by Pavel Emelyanov

[permalink] [raw]
Subject: Re: [PATCH 1/8] sunrpc: Factor out rpc_xprt freeing

> If you are redoing the patch, then could you please just get rid of the
> above forward declaration for xs_free_xprt, and instead just move the
> function itself further up the file?

Sure. Will do it soon.

> Cheers
> Trond