diff options
author | Andrey Ryabinin <aryabinin@virtuozzo.com> | 2015-10-07 07:39:55 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2015-10-23 15:57:27 -0400 |
commit | 0d0f4aab4e4d290138a4ae7f2ef8469e48c9a669 (patch) | |
tree | 7efb5dbfc6769b16a2f3415b5654efd83fd6d4db /fs | |
parent | 226453d8cfbd5f3bbdcef0d71e67186715bb811d (diff) |
lockd: get rid of reference-counted NSM RPC clients
Currently we have reference-counted per-net NSM RPC client
which created on the first monitor request and destroyed
after the last unmonitor request. It's needed because
RPC client need to know 'utsname()->nodename', but utsname()
might be NULL when nsm_unmonitor() called.
So instead of holding the rpc client we could just save nodename
in struct nlm_host and pass it to the rpc_create().
Thus ther is no need in keeping rpc client until last
unmonitor request. We could create separate RPC clients
for each monitor/unmonitor requests.
Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/lockd/host.c | 1 | ||||
-rw-r--r-- | fs/lockd/mon.c | 89 | ||||
-rw-r--r-- | fs/lockd/netns.h | 3 | ||||
-rw-r--r-- | fs/lockd/svc.c | 1 |
4 files changed, 16 insertions, 78 deletions
diff --git a/fs/lockd/host.c b/fs/lockd/host.c index b5f3c3ab0d5f..d716c9993a26 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c | |||
@@ -161,6 +161,7 @@ static struct nlm_host *nlm_alloc_host(struct nlm_lookup_host_info *ni, | |||
161 | host->h_nsmhandle = nsm; | 161 | host->h_nsmhandle = nsm; |
162 | host->h_addrbuf = nsm->sm_addrbuf; | 162 | host->h_addrbuf = nsm->sm_addrbuf; |
163 | host->net = ni->net; | 163 | host->net = ni->net; |
164 | strlcpy(host->nodename, utsname()->nodename, sizeof(host->nodename)); | ||
164 | 165 | ||
165 | out: | 166 | out: |
166 | return host; | 167 | return host; |
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index 6c05cd17e520..19166d4a8d31 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c | |||
@@ -42,7 +42,7 @@ struct nsm_args { | |||
42 | u32 proc; | 42 | u32 proc; |
43 | 43 | ||
44 | char *mon_name; | 44 | char *mon_name; |
45 | char *nodename; | 45 | const char *nodename; |
46 | }; | 46 | }; |
47 | 47 | ||
48 | struct nsm_res { | 48 | struct nsm_res { |
@@ -86,69 +86,18 @@ static struct rpc_clnt *nsm_create(struct net *net, const char *nodename) | |||
86 | return rpc_create(&args); | 86 | return rpc_create(&args); |
87 | } | 87 | } |
88 | 88 | ||
89 | static struct rpc_clnt *nsm_client_set(struct lockd_net *ln, | ||
90 | struct rpc_clnt *clnt) | ||
91 | { | ||
92 | spin_lock(&ln->nsm_clnt_lock); | ||
93 | if (ln->nsm_users == 0) { | ||
94 | if (clnt == NULL) | ||
95 | goto out; | ||
96 | ln->nsm_clnt = clnt; | ||
97 | } | ||
98 | clnt = ln->nsm_clnt; | ||
99 | ln->nsm_users++; | ||
100 | out: | ||
101 | spin_unlock(&ln->nsm_clnt_lock); | ||
102 | return clnt; | ||
103 | } | ||
104 | |||
105 | static struct rpc_clnt *nsm_client_get(struct net *net, const char *nodename) | ||
106 | { | ||
107 | struct rpc_clnt *clnt, *new; | ||
108 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
109 | |||
110 | clnt = nsm_client_set(ln, NULL); | ||
111 | if (clnt != NULL) | ||
112 | goto out; | ||
113 | |||
114 | clnt = new = nsm_create(net, nodename); | ||
115 | if (IS_ERR(clnt)) | ||
116 | goto out; | ||
117 | |||
118 | clnt = nsm_client_set(ln, new); | ||
119 | if (clnt != new) | ||
120 | rpc_shutdown_client(new); | ||
121 | out: | ||
122 | return clnt; | ||
123 | } | ||
124 | |||
125 | static void nsm_client_put(struct net *net) | ||
126 | { | ||
127 | struct lockd_net *ln = net_generic(net, lockd_net_id); | ||
128 | struct rpc_clnt *clnt = NULL; | ||
129 | |||
130 | spin_lock(&ln->nsm_clnt_lock); | ||
131 | ln->nsm_users--; | ||
132 | if (ln->nsm_users == 0) { | ||
133 | clnt = ln->nsm_clnt; | ||
134 | ln->nsm_clnt = NULL; | ||
135 | } | ||
136 | spin_unlock(&ln->nsm_clnt_lock); | ||
137 | if (clnt != NULL) | ||
138 | rpc_shutdown_client(clnt); | ||
139 | } | ||
140 | |||
141 | static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res, | 89 | static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res, |
142 | struct rpc_clnt *clnt) | 90 | const struct nlm_host *host) |
143 | { | 91 | { |
144 | int status; | 92 | int status; |
93 | struct rpc_clnt *clnt; | ||
145 | struct nsm_args args = { | 94 | struct nsm_args args = { |
146 | .priv = &nsm->sm_priv, | 95 | .priv = &nsm->sm_priv, |
147 | .prog = NLM_PROGRAM, | 96 | .prog = NLM_PROGRAM, |
148 | .vers = 3, | 97 | .vers = 3, |
149 | .proc = NLMPROC_NSM_NOTIFY, | 98 | .proc = NLMPROC_NSM_NOTIFY, |
150 | .mon_name = nsm->sm_mon_name, | 99 | .mon_name = nsm->sm_mon_name, |
151 | .nodename = clnt->cl_nodename, | 100 | .nodename = host->nodename, |
152 | }; | 101 | }; |
153 | struct rpc_message msg = { | 102 | struct rpc_message msg = { |
154 | .rpc_argp = &args, | 103 | .rpc_argp = &args, |
@@ -157,6 +106,13 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res, | |||
157 | 106 | ||
158 | memset(res, 0, sizeof(*res)); | 107 | memset(res, 0, sizeof(*res)); |
159 | 108 | ||
109 | clnt = nsm_create(host->net, host->nodename); | ||
110 | if (IS_ERR(clnt)) { | ||
111 | dprintk("lockd: failed to create NSM upcall transport, " | ||
112 | "status=%ld, net=%p\n", PTR_ERR(clnt), host->net); | ||
113 | return PTR_ERR(clnt); | ||
114 | } | ||
115 | |||
160 | msg.rpc_proc = &clnt->cl_procinfo[proc]; | 116 | msg.rpc_proc = &clnt->cl_procinfo[proc]; |
161 | status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFTCONN); | 117 | status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFTCONN); |
162 | if (status == -ECONNREFUSED) { | 118 | if (status == -ECONNREFUSED) { |
@@ -170,6 +126,8 @@ static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res, | |||
170 | status); | 126 | status); |
171 | else | 127 | else |
172 | status = 0; | 128 | status = 0; |
129 | |||
130 | rpc_shutdown_client(clnt); | ||
173 | return status; | 131 | return status; |
174 | } | 132 | } |
175 | 133 | ||
@@ -189,32 +147,19 @@ int nsm_monitor(const struct nlm_host *host) | |||
189 | struct nsm_handle *nsm = host->h_nsmhandle; | 147 | struct nsm_handle *nsm = host->h_nsmhandle; |
190 | struct nsm_res res; | 148 | struct nsm_res res; |
191 | int status; | 149 | int status; |
192 | struct rpc_clnt *clnt; | ||
193 | const char *nodename = NULL; | ||
194 | 150 | ||
195 | dprintk("lockd: nsm_monitor(%s)\n", nsm->sm_name); | 151 | dprintk("lockd: nsm_monitor(%s)\n", nsm->sm_name); |
196 | 152 | ||
197 | if (nsm->sm_monitored) | 153 | if (nsm->sm_monitored) |
198 | return 0; | 154 | return 0; |
199 | 155 | ||
200 | if (host->h_rpcclnt) | ||
201 | nodename = host->h_rpcclnt->cl_nodename; | ||
202 | |||
203 | /* | 156 | /* |
204 | * Choose whether to record the caller_name or IP address of | 157 | * Choose whether to record the caller_name or IP address of |
205 | * this peer in the local rpc.statd's database. | 158 | * this peer in the local rpc.statd's database. |
206 | */ | 159 | */ |
207 | nsm->sm_mon_name = nsm_use_hostnames ? nsm->sm_name : nsm->sm_addrbuf; | 160 | nsm->sm_mon_name = nsm_use_hostnames ? nsm->sm_name : nsm->sm_addrbuf; |
208 | 161 | ||
209 | clnt = nsm_client_get(host->net, nodename); | 162 | status = nsm_mon_unmon(nsm, NSMPROC_MON, &res, host); |
210 | if (IS_ERR(clnt)) { | ||
211 | status = PTR_ERR(clnt); | ||
212 | dprintk("lockd: failed to create NSM upcall transport, " | ||
213 | "status=%d, net=%p\n", status, host->net); | ||
214 | return status; | ||
215 | } | ||
216 | |||
217 | status = nsm_mon_unmon(nsm, NSMPROC_MON, &res, clnt); | ||
218 | if (unlikely(res.status != 0)) | 163 | if (unlikely(res.status != 0)) |
219 | status = -EIO; | 164 | status = -EIO; |
220 | if (unlikely(status < 0)) { | 165 | if (unlikely(status < 0)) { |
@@ -246,11 +191,9 @@ void nsm_unmonitor(const struct nlm_host *host) | |||
246 | 191 | ||
247 | if (atomic_read(&nsm->sm_count) == 1 | 192 | if (atomic_read(&nsm->sm_count) == 1 |
248 | && nsm->sm_monitored && !nsm->sm_sticky) { | 193 | && nsm->sm_monitored && !nsm->sm_sticky) { |
249 | struct lockd_net *ln = net_generic(host->net, lockd_net_id); | ||
250 | |||
251 | dprintk("lockd: nsm_unmonitor(%s)\n", nsm->sm_name); | 194 | dprintk("lockd: nsm_unmonitor(%s)\n", nsm->sm_name); |
252 | 195 | ||
253 | status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res, ln->nsm_clnt); | 196 | status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res, host); |
254 | if (res.status != 0) | 197 | if (res.status != 0) |
255 | status = -EIO; | 198 | status = -EIO; |
256 | if (status < 0) | 199 | if (status < 0) |
@@ -258,8 +201,6 @@ void nsm_unmonitor(const struct nlm_host *host) | |||
258 | nsm->sm_name); | 201 | nsm->sm_name); |
259 | else | 202 | else |
260 | nsm->sm_monitored = 0; | 203 | nsm->sm_monitored = 0; |
261 | |||
262 | nsm_client_put(host->net); | ||
263 | } | 204 | } |
264 | } | 205 | } |
265 | 206 | ||
diff --git a/fs/lockd/netns.h b/fs/lockd/netns.h index 89fe011b1335..5426189406c1 100644 --- a/fs/lockd/netns.h +++ b/fs/lockd/netns.h | |||
@@ -12,9 +12,6 @@ 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 | 14 | ||
15 | spinlock_t nsm_clnt_lock; | ||
16 | unsigned int nsm_users; | ||
17 | struct rpc_clnt *nsm_clnt; | ||
18 | struct list_head nsm_handles; | 15 | struct list_head nsm_handles; |
19 | }; | 16 | }; |
20 | 17 | ||
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 0dff13f41808..5f31ebd96c06 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
@@ -592,7 +592,6 @@ static int lockd_init_net(struct net *net) | |||
592 | INIT_DELAYED_WORK(&ln->grace_period_end, grace_ender); | 592 | INIT_DELAYED_WORK(&ln->grace_period_end, grace_ender); |
593 | INIT_LIST_HEAD(&ln->lockd_manager.list); | 593 | INIT_LIST_HEAD(&ln->lockd_manager.list); |
594 | ln->lockd_manager.block_opens = false; | 594 | ln->lockd_manager.block_opens = false; |
595 | spin_lock_init(&ln->nsm_clnt_lock); | ||
596 | INIT_LIST_HEAD(&ln->nsm_handles); | 595 | INIT_LIST_HEAD(&ln->nsm_handles); |
597 | return 0; | 596 | return 0; |
598 | } | 597 | } |