提交 e9406db2 编写于 作者: S Stanislav Kinsbursky 提交者: Trond Myklebust

lockd: per-net NSM client creation and destruction helpers introduced

NSM RPC client can be required on NFSv3 umount, when child reaper is dying (and
destroying it's mount namespace). It means, that current nsproxy is set to
NULL already, but creation of RPC client requires UTS namespace for gaining
hostname string.
This patch introduces reference counted NFS RPC clients creation and
destruction helpers (similar to RPCBIND RPC clients).
Signed-off-by: NStanislav Kinsbursky <skinsbursky@parallels.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: NTrond Myklebust <Trond.Myklebust@netapp.com>
上级 1dc42e04
...@@ -19,6 +19,8 @@ ...@@ -19,6 +19,8 @@
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include "netns.h"
#define NLMDBG_FACILITY NLMDBG_MONITOR #define NLMDBG_FACILITY NLMDBG_MONITOR
#define NSM_PROGRAM 100024 #define NSM_PROGRAM 100024
#define NSM_VERSION 1 #define NSM_VERSION 1
...@@ -70,7 +72,7 @@ static struct rpc_clnt *nsm_create(struct net *net) ...@@ -70,7 +72,7 @@ static struct rpc_clnt *nsm_create(struct net *net)
}; };
struct rpc_create_args args = { struct rpc_create_args args = {
.net = net, .net = net,
.protocol = XPRT_TRANSPORT_UDP, .protocol = XPRT_TRANSPORT_TCP,
.address = (struct sockaddr *)&sin, .address = (struct sockaddr *)&sin,
.addrsize = sizeof(sin), .addrsize = sizeof(sin),
.servername = "rpc.statd", .servername = "rpc.statd",
...@@ -83,6 +85,51 @@ static struct rpc_clnt *nsm_create(struct net *net) ...@@ -83,6 +85,51 @@ static struct rpc_clnt *nsm_create(struct net *net)
return rpc_create(&args); 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, static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
struct net *net) struct net *net)
{ {
...@@ -111,7 +158,7 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res, ...@@ -111,7 +158,7 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
memset(res, 0, sizeof(*res)); memset(res, 0, sizeof(*res));
msg.rpc_proc = &clnt->cl_procinfo[proc]; 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) if (status < 0)
dprintk("lockd: NSM upcall RPC failed, status=%d\n", dprintk("lockd: NSM upcall RPC failed, status=%d\n",
status); status);
......
...@@ -12,6 +12,10 @@ struct lockd_net { ...@@ -12,6 +12,10 @@ struct lockd_net {
struct delayed_work grace_period_end; struct delayed_work grace_period_end;
struct lock_manager lockd_manager; struct lock_manager lockd_manager;
struct list_head grace_list; struct list_head grace_list;
spinlock_t nsm_clnt_lock;
unsigned int nsm_users;
struct rpc_clnt *nsm_clnt;
}; };
extern int lockd_net_id; extern int lockd_net_id;
......
...@@ -596,6 +596,7 @@ static int lockd_init_net(struct net *net) ...@@ -596,6 +596,7 @@ static int lockd_init_net(struct net *net)
INIT_DELAYED_WORK(&ln->grace_period_end, grace_ender); INIT_DELAYED_WORK(&ln->grace_period_end, grace_ender);
INIT_LIST_HEAD(&ln->grace_list); INIT_LIST_HEAD(&ln->grace_list);
spin_lock_init(&ln->nsm_clnt_lock);
return 0; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册