diff options
author | Stanislav Kinsbursky <skinsbursky@parallels.com> | 2012-05-02 08:08:38 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2012-05-31 20:29:39 -0400 |
commit | 9793f7c88937e7ac07305ab1af1a519225836823 (patch) | |
tree | 48a4283a15cb0d5a427e722075fe546cc8cdcc53 | |
parent | c52226daf553b21891f39777d78a54ea4e7e8654 (diff) |
SUNRPC: new svc_bind() routine introduced
This new routine is responsible for service registration in a specified
network context.
The idea is to separate service creation from per-net operations.
Note also: since registering service with svc_bind() can fail, the
service will be destroyed and during destruction it will try to
unregister itself from rpcbind. In this case unregistration has to be
skipped.
Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r-- | fs/lockd/svc.c | 6 | ||||
-rw-r--r-- | fs/nfs/callback.c | 8 | ||||
-rw-r--r-- | fs/nfsd/nfssvc.c | 9 | ||||
-rw-r--r-- | include/linux/sunrpc/svc.h | 1 | ||||
-rw-r--r-- | net/sunrpc/rpcb_clnt.c | 12 | ||||
-rw-r--r-- | net/sunrpc/svc.c | 19 |
6 files changed, 41 insertions, 14 deletions
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 1ead0750cdbb..b7e92ed56885 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
@@ -324,6 +324,12 @@ int lockd_up(struct net *net) | |||
324 | goto out; | 324 | goto out; |
325 | } | 325 | } |
326 | 326 | ||
327 | error = svc_bind(serv, net); | ||
328 | if (error < 0) { | ||
329 | printk(KERN_WARNING "lockd_up: bind service failed\n"); | ||
330 | goto destroy_and_out; | ||
331 | } | ||
332 | |||
327 | error = make_socks(serv, net); | 333 | error = make_socks(serv, net); |
328 | if (error < 0) | 334 | if (error < 0) |
329 | goto destroy_and_out; | 335 | goto destroy_and_out; |
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index eb95f5091c1a..26b38fb8102e 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/kthread.h> | 17 | #include <linux/kthread.h> |
18 | #include <linux/sunrpc/svcauth_gss.h> | 18 | #include <linux/sunrpc/svcauth_gss.h> |
19 | #include <linux/sunrpc/bc_xprt.h> | 19 | #include <linux/sunrpc/bc_xprt.h> |
20 | #include <linux/nsproxy.h> | ||
20 | 21 | ||
21 | #include <net/inet_sock.h> | 22 | #include <net/inet_sock.h> |
22 | 23 | ||
@@ -253,6 +254,7 @@ int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt) | |||
253 | char svc_name[12]; | 254 | char svc_name[12]; |
254 | int ret = 0; | 255 | int ret = 0; |
255 | int minorversion_setup; | 256 | int minorversion_setup; |
257 | struct net *net = current->nsproxy->net_ns; | ||
256 | 258 | ||
257 | mutex_lock(&nfs_callback_mutex); | 259 | mutex_lock(&nfs_callback_mutex); |
258 | if (cb_info->users++ || cb_info->task != NULL) { | 260 | if (cb_info->users++ || cb_info->task != NULL) { |
@@ -265,6 +267,12 @@ int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt) | |||
265 | goto out_err; | 267 | goto out_err; |
266 | } | 268 | } |
267 | 269 | ||
270 | ret = svc_bind(serv, net); | ||
271 | if (ret < 0) { | ||
272 | printk(KERN_WARNING "NFS: bind callback service failed\n"); | ||
273 | goto out_err; | ||
274 | } | ||
275 | |||
268 | minorversion_setup = nfs_minorversion_callback_svc_setup(minorversion, | 276 | minorversion_setup = nfs_minorversion_callback_svc_setup(minorversion, |
269 | serv, xprt, &rqstp, &callback_svc); | 277 | serv, xprt, &rqstp, &callback_svc); |
270 | if (!minorversion_setup) { | 278 | if (!minorversion_setup) { |
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index cb4d51d8cbdb..0762f3c9e0fb 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/fs_struct.h> | 12 | #include <linux/fs_struct.h> |
13 | #include <linux/swap.h> | 13 | #include <linux/swap.h> |
14 | #include <linux/nsproxy.h> | ||
14 | 15 | ||
15 | #include <linux/sunrpc/stats.h> | 16 | #include <linux/sunrpc/stats.h> |
16 | #include <linux/sunrpc/svcsock.h> | 17 | #include <linux/sunrpc/svcsock.h> |
@@ -330,6 +331,8 @@ static int nfsd_get_default_max_blksize(void) | |||
330 | 331 | ||
331 | int nfsd_create_serv(void) | 332 | int nfsd_create_serv(void) |
332 | { | 333 | { |
334 | int error; | ||
335 | |||
333 | WARN_ON(!mutex_is_locked(&nfsd_mutex)); | 336 | WARN_ON(!mutex_is_locked(&nfsd_mutex)); |
334 | if (nfsd_serv) { | 337 | if (nfsd_serv) { |
335 | svc_get(nfsd_serv); | 338 | svc_get(nfsd_serv); |
@@ -343,6 +346,12 @@ int nfsd_create_serv(void) | |||
343 | if (nfsd_serv == NULL) | 346 | if (nfsd_serv == NULL) |
344 | return -ENOMEM; | 347 | return -ENOMEM; |
345 | 348 | ||
349 | error = svc_bind(nfsd_serv, current->nsproxy->net_ns); | ||
350 | if (error < 0) { | ||
351 | svc_destroy(nfsd_serv); | ||
352 | return error; | ||
353 | } | ||
354 | |||
346 | set_max_drc(); | 355 | set_max_drc(); |
347 | do_gettimeofday(&nfssvc_boot); /* record boot time */ | 356 | do_gettimeofday(&nfssvc_boot); /* record boot time */ |
348 | return 0; | 357 | return 0; |
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 51b29ac45a8e..2b43e0214261 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h | |||
@@ -416,6 +416,7 @@ struct svc_procedure { | |||
416 | */ | 416 | */ |
417 | int svc_rpcb_setup(struct svc_serv *serv, struct net *net); | 417 | int svc_rpcb_setup(struct svc_serv *serv, struct net *net); |
418 | void svc_rpcb_cleanup(struct svc_serv *serv, struct net *net); | 418 | void svc_rpcb_cleanup(struct svc_serv *serv, struct net *net); |
419 | int svc_bind(struct svc_serv *serv, struct net *net); | ||
419 | struct svc_serv *svc_create(struct svc_program *, unsigned int, | 420 | struct svc_serv *svc_create(struct svc_program *, unsigned int, |
420 | void (*shutdown)(struct svc_serv *, struct net *net)); | 421 | void (*shutdown)(struct svc_serv *, struct net *net)); |
421 | struct svc_rqst *svc_prepare_thread(struct svc_serv *serv, | 422 | struct svc_rqst *svc_prepare_thread(struct svc_serv *serv, |
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 78ac39fd9fe7..4c38b33ab8a8 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c | |||
@@ -180,14 +180,16 @@ void rpcb_put_local(struct net *net) | |||
180 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | 180 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); |
181 | struct rpc_clnt *clnt = sn->rpcb_local_clnt; | 181 | struct rpc_clnt *clnt = sn->rpcb_local_clnt; |
182 | struct rpc_clnt *clnt4 = sn->rpcb_local_clnt4; | 182 | struct rpc_clnt *clnt4 = sn->rpcb_local_clnt4; |
183 | int shutdown; | 183 | int shutdown = 0; |
184 | 184 | ||
185 | spin_lock(&sn->rpcb_clnt_lock); | 185 | spin_lock(&sn->rpcb_clnt_lock); |
186 | if (--sn->rpcb_users == 0) { | 186 | if (sn->rpcb_users) { |
187 | sn->rpcb_local_clnt = NULL; | 187 | if (--sn->rpcb_users == 0) { |
188 | sn->rpcb_local_clnt4 = NULL; | 188 | sn->rpcb_local_clnt = NULL; |
189 | sn->rpcb_local_clnt4 = NULL; | ||
190 | } | ||
191 | shutdown = !sn->rpcb_users; | ||
189 | } | 192 | } |
190 | shutdown = !sn->rpcb_users; | ||
191 | spin_unlock(&sn->rpcb_clnt_lock); | 193 | spin_unlock(&sn->rpcb_clnt_lock); |
192 | 194 | ||
193 | if (shutdown) { | 195 | if (shutdown) { |
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 4153846984ac..e6d542cee0f3 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
@@ -407,6 +407,14 @@ static int svc_uses_rpcbind(struct svc_serv *serv) | |||
407 | return 0; | 407 | return 0; |
408 | } | 408 | } |
409 | 409 | ||
410 | int svc_bind(struct svc_serv *serv, struct net *net) | ||
411 | { | ||
412 | if (!svc_uses_rpcbind(serv)) | ||
413 | return 0; | ||
414 | return svc_rpcb_setup(serv, net); | ||
415 | } | ||
416 | EXPORT_SYMBOL_GPL(svc_bind); | ||
417 | |||
410 | /* | 418 | /* |
411 | * Create an RPC service | 419 | * Create an RPC service |
412 | */ | 420 | */ |
@@ -471,15 +479,8 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools, | |||
471 | spin_lock_init(&pool->sp_lock); | 479 | spin_lock_init(&pool->sp_lock); |
472 | } | 480 | } |
473 | 481 | ||
474 | if (svc_uses_rpcbind(serv)) { | 482 | if (svc_uses_rpcbind(serv) && (!serv->sv_shutdown)) |
475 | if (svc_rpcb_setup(serv, current->nsproxy->net_ns) < 0) { | 483 | serv->sv_shutdown = svc_rpcb_cleanup; |
476 | kfree(serv->sv_pools); | ||
477 | kfree(serv); | ||
478 | return NULL; | ||
479 | } | ||
480 | if (!serv->sv_shutdown) | ||
481 | serv->sv_shutdown = svc_rpcb_cleanup; | ||
482 | } | ||
483 | 484 | ||
484 | return serv; | 485 | return serv; |
485 | } | 486 | } |