X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=fs%2Flockd%2Fmon.c;h=e0bc36e74ceb6f82dd025dfa9f3c9de2ef0f562f;hb=303a7ce92064c285a04c870f2dc0192fdb2968cb;hp=7ef14b3c5bee9460609d863a973f0dfad93f163c;hpb=4a1e8ebc5e5918079109cc1cd1c44c2f0fd0e11b;p=pandora-kernel.git diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index 7ef14b3c5bee..e0bc36e74ceb 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c @@ -19,6 +19,8 @@ #include +#include "netns.h" + #define NLMDBG_FACILITY NLMDBG_MONITOR #define NSM_PROGRAM 100024 #define NSM_VERSION 1 @@ -40,6 +42,7 @@ struct nsm_args { u32 proc; char *mon_name; + char *nodename; }; struct nsm_res { @@ -70,7 +73,7 @@ static struct rpc_clnt *nsm_create(struct net *net) }; struct rpc_create_args args = { .net = net, - .protocol = XPRT_TRANSPORT_UDP, + .protocol = XPRT_TRANSPORT_TCP, .address = (struct sockaddr *)&sin, .addrsize = sizeof(sin), .servername = "rpc.statd", @@ -83,6 +86,51 @@ static struct rpc_clnt *nsm_create(struct net *net) return rpc_create(&args); } +__maybe_unused static struct rpc_clnt *nsm_client_get(struct net *net) +{ + static DEFINE_MUTEX(nsm_create_mutex); + struct rpc_clnt *clnt; + struct lockd_net *ln = net_generic(net, lockd_net_id); + + spin_lock(&ln->nsm_clnt_lock); + if (ln->nsm_users) { + ln->nsm_users++; + clnt = ln->nsm_clnt; + spin_unlock(&ln->nsm_clnt_lock); + goto out; + } + spin_unlock(&ln->nsm_clnt_lock); + + mutex_lock(&nsm_create_mutex); + clnt = nsm_create(net); + if (!IS_ERR(clnt)) { + ln->nsm_clnt = clnt; + smp_wmb(); + ln->nsm_users = 1; + } + mutex_unlock(&nsm_create_mutex); +out: + return clnt; +} + +__maybe_unused static void nsm_client_put(struct net *net) +{ + struct lockd_net *ln = net_generic(net, lockd_net_id); + struct rpc_clnt *clnt = ln->nsm_clnt; + int shutdown = 0; + + spin_lock(&ln->nsm_clnt_lock); + if (ln->nsm_users) { + if (--ln->nsm_users) + ln->nsm_clnt = NULL; + shutdown = !ln->nsm_users; + } + spin_unlock(&ln->nsm_clnt_lock); + + if (shutdown) + rpc_shutdown_client(clnt); +} + static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res, struct net *net) { @@ -94,6 +142,7 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res, .vers = 3, .proc = NLMPROC_NSM_NOTIFY, .mon_name = nsm->sm_mon_name, + .nodename = utsname()->nodename, }; struct rpc_message msg = { .rpc_argp = &args, @@ -111,7 +160,7 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res, memset(res, 0, sizeof(*res)); msg.rpc_proc = &clnt->cl_procinfo[proc]; - status = rpc_call_sync(clnt, &msg, 0); + status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFTCONN); if (status < 0) dprintk("lockd: NSM upcall RPC failed, status=%d\n", status); @@ -430,7 +479,7 @@ static void encode_my_id(struct xdr_stream *xdr, const struct nsm_args *argp) { __be32 *p; - encode_nsm_string(xdr, utsname()->nodename); + encode_nsm_string(xdr, argp->nodename); p = xdr_reserve_space(xdr, 4 + 4 + 4); *p++ = cpu_to_be32(argp->prog); *p++ = cpu_to_be32(argp->vers);