diff options
-rw-r--r-- | fs/lockd/mon.c | 51 | ||||
-rw-r--r-- | fs/lockd/netns.h | 4 | ||||
-rw-r--r-- | fs/lockd/svc.c | 1 |
3 files changed, 54 insertions, 2 deletions
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index 7ef14b3c5bee..38f240e104ce 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c | |||
@@ -19,6 +19,8 @@ | |||
19 | 19 | ||
20 | #include <asm/unaligned.h> | 20 | #include <asm/unaligned.h> |
21 | 21 | ||
22 | #include "netns.h" | ||
23 | |||
22 | #define NLMDBG_FACILITY NLMDBG_MONITOR | 24 | #define NLMDBG_FACILITY NLMDBG_MONITOR |
23 | #define NSM_PROGRAM 100024 | 25 | #define NSM_PROGRAM 100024 |
24 | #define NSM_VERSION 1 | 26 | #define NSM_VERSION 1 |
@@ -70,7 +72,7 @@ static struct rpc_clnt *nsm_create(struct net *net) | |||
70 | }; | 72 | }; |
71 | struct rpc_create_args args = { | 73 | struct rpc_create_args args = { |
72 | .net = net, | 74 | .net = net, |
73 | .protocol = XPRT_TRANSPORT_UDP, | 75 | .protocol = XPRT_TRANSPORT_TCP, |
74 | .address = (struct sockaddr *)&sin, | 76 | .address = (struct sockaddr *)&sin, |
75 | .addrsize = sizeof(sin), | 77 | .addrsize = sizeof(sin), |
76 | .servername = "rpc.statd", | 78 | .servername = "rpc.statd", |
@@ -83,6 +85,51 @@ static struct rpc_clnt *nsm_create(struct net *net) | |||
83 | return rpc_create(&args); | 85 | return rpc_create(&args); |
84 | } | 86 | } |
85 | 87 | ||
88 | __maybe_unused static struct rpc_clnt *nsm_client_get(struct net *net) | ||
89 | { | ||
90 | static DEFINE_MUTEX(nsm_create_mutex); | ||
91 | struct rpc_clnt *clnt; | ||
92 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
93 | |||
94 | spin_lock(&ln->nsm_clnt_lock); | ||
95 | if (ln->nsm_users) { | ||
96 | ln->nsm_users++; | ||
97 | clnt = ln->nsm_clnt; | ||
98 | spin_unlock(&ln->nsm_clnt_lock); | ||
99 | goto out; | ||
100 | } | ||
101 | spin_unlock(&ln->nsm_clnt_lock); | ||
102 | |||
103 | mutex_lock(&nsm_create_mutex); | ||
104 | clnt = nsm_create(net); | ||
105 | if (!IS_ERR(clnt)) { | ||
106 | ln->nsm_clnt = clnt; | ||
107 | smp_wmb(); | ||
108 | ln->nsm_users = 1; | ||
109 | } | ||
110 | mutex_unlock(&nsm_create_mutex); | ||
111 | out: | ||
112 | return clnt; | ||
113 | } | ||
114 | |||
115 | __maybe_unused static void nsm_client_put(struct net *net) | ||
116 | { | ||
117 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
118 | struct rpc_clnt *clnt = ln->nsm_clnt; | ||
119 | int shutdown = 0; | ||
120 | |||
121 | spin_lock(&ln->nsm_clnt_lock); | ||
122 | if (ln->nsm_users) { | ||
123 | if (--ln->nsm_users) | ||
124 | ln->nsm_clnt = NULL; | ||
125 | shutdown = !ln->nsm_users; | ||
126 | } | ||
127 | spin_unlock(&ln->nsm_clnt_lock); | ||
128 | |||
129 | if (shutdown) | ||
130 | rpc_shutdown_client(clnt); | ||
131 | } | ||
132 | |||
86 | static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res, | 133 | static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res, |
87 | struct net *net) | 134 | struct net *net) |
88 | { | 135 | { |
@@ -111,7 +158,7 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res, | |||
111 | memset(res, 0, sizeof(*res)); | 158 | memset(res, 0, sizeof(*res)); |
112 | 159 | ||
113 | msg.rpc_proc = &clnt->cl_procinfo[proc]; | 160 | msg.rpc_proc = &clnt->cl_procinfo[proc]; |
114 | status = rpc_call_sync(clnt, &msg, 0); | 161 | status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFTCONN); |
115 | if (status < 0) | 162 | if (status < 0) |
116 | dprintk("lockd: NSM upcall RPC failed, status=%d\n", | 163 | dprintk("lockd: NSM upcall RPC failed, status=%d\n", |
117 | status); | 164 | status); |
diff --git a/fs/lockd/netns.h b/fs/lockd/netns.h index 4eee248ba96e..5010b55628b4 100644 --- a/fs/lockd/netns.h +++ b/fs/lockd/netns.h | |||
@@ -12,6 +12,10 @@ struct lockd_net { | |||
12 | struct delayed_work grace_period_end; | 12 | struct delayed_work grace_period_end; |
13 | struct lock_manager lockd_manager; | 13 | struct lock_manager lockd_manager; |
14 | struct list_head grace_list; | 14 | struct list_head grace_list; |
15 | |||
16 | spinlock_t nsm_clnt_lock; | ||
17 | unsigned int nsm_users; | ||
18 | struct rpc_clnt *nsm_clnt; | ||
15 | }; | 19 | }; |
16 | 20 | ||
17 | extern int lockd_net_id; | 21 | extern int lockd_net_id; |
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 31a63f87b806..7e355870d519 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
@@ -596,6 +596,7 @@ static int lockd_init_net(struct net *net) | |||
596 | 596 | ||
597 | INIT_DELAYED_WORK(&ln->grace_period_end, grace_ender); | 597 | INIT_DELAYED_WORK(&ln->grace_period_end, grace_ender); |
598 | INIT_LIST_HEAD(&ln->grace_list); | 598 | INIT_LIST_HEAD(&ln->grace_list); |
599 | spin_lock_init(&ln->nsm_clnt_lock); | ||
599 | return 0; | 600 | return 0; |
600 | } | 601 | } |
601 | 602 | ||