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 <[email protected]>
Signed-off-by: J. Bruce Fields <[email protected]>
This commit is contained in:
Stanislav Kinsbursky 2012-05-02 16:08:38 +04:00 • committed by J. Bruce Fields
commit 9793f7c889
6 changed files with 41 additions and 14 deletions

View file

@ -180,14 +180,16 @@ void rpcb_put_local(struct net *net)
struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
struct rpc_clnt *clnt = sn->rpcb_local_clnt;
struct rpc_clnt *clnt4 = sn->rpcb_local_clnt4;
int shutdown;
int shutdown = 0;
spin_lock(&sn->rpcb_clnt_lock);
if (--sn->rpcb_users == 0) {
sn->rpcb_local_clnt = NULL;
sn->rpcb_local_clnt4 = NULL;
if (sn->rpcb_users) {
if (--sn->rpcb_users == 0) {
sn->rpcb_local_clnt = NULL;
sn->rpcb_local_clnt4 = NULL;
}
shutdown = !sn->rpcb_users;
}
shutdown = !sn->rpcb_users;
spin_unlock(&sn->rpcb_clnt_lock);
if (shutdown) {

View file

@ -407,6 +407,14 @@ static int svc_uses_rpcbind(struct svc_serv *serv)
return 0;
}
int svc_bind(struct svc_serv *serv, struct net *net)
{
if (!svc_uses_rpcbind(serv))
return 0;
return svc_rpcb_setup(serv, net);
}
EXPORT_SYMBOL_GPL(svc_bind);
/*
* Create an RPC service
*/
@ -471,15 +479,8 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
spin_lock_init(&pool->sp_lock);
}
if (svc_uses_rpcbind(serv)) {
if (svc_rpcb_setup(serv, current->nsproxy->net_ns) < 0) {
kfree(serv->sv_pools);
kfree(serv);
return NULL;
}
if (!serv->sv_shutdown)
serv->sv_shutdown = svc_rpcb_cleanup;
}
if (svc_uses_rpcbind(serv) && (!serv->sv_shutdown))
serv->sv_shutdown = svc_rpcb_cleanup;
return serv;
}