aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStanislav Kinsbursky <skinsbursky@parallels.com>2012-03-29 10:54:33 -0400
committerJ. Bruce Fields <bfields@redhat.com>2012-04-11 17:55:06 -0400
commite3f70eadb7dddfb5a2bb9afff7abfc6ee17a29d0 (patch)
tree688a94f2c86e0d7c637609239925f94f8ee08626
parentf890edbbeff6928b7db0c6179a9036cbd4f0efbf (diff)
Lockd: pass network namespace to creation and destruction routines
v2: dereference of most probably already released nlm_host removed in nlmclnt_done() and reclaimer(). These routines are called from locks reclaimer() kernel thread. This thread works in "init_net" network context and currently relays on persence on lockd thread and it's per-net resources. Thus lockd_up() and lockd_down() can't relay on current network context. So let's pass corrent one into them. Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r--fs/lockd/clntlock.c13
-rw-r--r--fs/lockd/svc.c7
-rw-r--r--fs/nfsd/nfssvc.c6
-rw-r--r--include/linux/lockd/bind.h4
4 files changed, 16 insertions, 14 deletions
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c
index ba1dc2eebd1e..ca0a08001449 100644
--- a/fs/lockd/clntlock.c
+++ b/fs/lockd/clntlock.c
@@ -56,7 +56,7 @@ struct nlm_host *nlmclnt_init(const struct nlmclnt_initdata *nlm_init)
56 u32 nlm_version = (nlm_init->nfs_version == 2) ? 1 : 4; 56 u32 nlm_version = (nlm_init->nfs_version == 2) ? 1 : 4;
57 int status; 57 int status;
58 58
59 status = lockd_up(); 59 status = lockd_up(nlm_init->net);
60 if (status < 0) 60 if (status < 0)
61 return ERR_PTR(status); 61 return ERR_PTR(status);
62 62
@@ -65,7 +65,7 @@ struct nlm_host *nlmclnt_init(const struct nlmclnt_initdata *nlm_init)
65 nlm_init->hostname, nlm_init->noresvport, 65 nlm_init->hostname, nlm_init->noresvport,
66 nlm_init->net); 66 nlm_init->net);
67 if (host == NULL) { 67 if (host == NULL) {
68 lockd_down(); 68 lockd_down(nlm_init->net);
69 return ERR_PTR(-ENOLCK); 69 return ERR_PTR(-ENOLCK);
70 } 70 }
71 71
@@ -80,8 +80,10 @@ EXPORT_SYMBOL_GPL(nlmclnt_init);
80 */ 80 */
81void nlmclnt_done(struct nlm_host *host) 81void nlmclnt_done(struct nlm_host *host)
82{ 82{
83 struct net *net = host->net;
84
83 nlmclnt_release_host(host); 85 nlmclnt_release_host(host);
84 lockd_down(); 86 lockd_down(net);
85} 87}
86EXPORT_SYMBOL_GPL(nlmclnt_done); 88EXPORT_SYMBOL_GPL(nlmclnt_done);
87 89
@@ -220,11 +222,12 @@ reclaimer(void *ptr)
220 struct nlm_wait *block; 222 struct nlm_wait *block;
221 struct file_lock *fl, *next; 223 struct file_lock *fl, *next;
222 u32 nsmstate; 224 u32 nsmstate;
225 struct net *net = host->net;
223 226
224 allow_signal(SIGKILL); 227 allow_signal(SIGKILL);
225 228
226 down_write(&host->h_rwsem); 229 down_write(&host->h_rwsem);
227 lockd_up(); /* note: this cannot fail as lockd is already running */ 230 lockd_up(net); /* note: this cannot fail as lockd is already running */
228 231
229 dprintk("lockd: reclaiming locks for host %s\n", host->h_name); 232 dprintk("lockd: reclaiming locks for host %s\n", host->h_name);
230 233
@@ -275,6 +278,6 @@ restart:
275 278
276 /* Release host handle after use */ 279 /* Release host handle after use */
277 nlmclnt_release_host(host); 280 nlmclnt_release_host(host);
278 lockd_down(); 281 lockd_down(net);
279 return 0; 282 return 0;
280} 283}
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index f49b9afc4436..1ead0750cdbb 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -295,11 +295,10 @@ static void lockd_down_net(struct net *net)
295/* 295/*
296 * Bring up the lockd process if it's not already up. 296 * Bring up the lockd process if it's not already up.
297 */ 297 */
298int lockd_up(void) 298int lockd_up(struct net *net)
299{ 299{
300 struct svc_serv *serv; 300 struct svc_serv *serv;
301 int error = 0; 301 int error = 0;
302 struct net *net = current->nsproxy->net_ns;
303 302
304 mutex_lock(&nlmsvc_mutex); 303 mutex_lock(&nlmsvc_mutex);
305 /* 304 /*
@@ -378,12 +377,12 @@ EXPORT_SYMBOL_GPL(lockd_up);
378 * Decrement the user count and bring down lockd if we're the last. 377 * Decrement the user count and bring down lockd if we're the last.
379 */ 378 */
380void 379void
381lockd_down(void) 380lockd_down(struct net *net)
382{ 381{
383 mutex_lock(&nlmsvc_mutex); 382 mutex_lock(&nlmsvc_mutex);
384 if (nlmsvc_users) { 383 if (nlmsvc_users) {
385 if (--nlmsvc_users) { 384 if (--nlmsvc_users) {
386 lockd_down_net(current->nsproxy->net_ns); 385 lockd_down_net(net);
387 goto out; 386 goto out;
388 } 387 }
389 } else { 388 } else {
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 28dfad39f0c5..78e521392df1 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -220,7 +220,7 @@ static int nfsd_startup(unsigned short port, int nrservs)
220 ret = nfsd_init_socks(port); 220 ret = nfsd_init_socks(port);
221 if (ret) 221 if (ret)
222 goto out_racache; 222 goto out_racache;
223 ret = lockd_up(); 223 ret = lockd_up(&init_net);
224 if (ret) 224 if (ret)
225 goto out_racache; 225 goto out_racache;
226 ret = nfs4_state_start(); 226 ret = nfs4_state_start();
@@ -229,7 +229,7 @@ static int nfsd_startup(unsigned short port, int nrservs)
229 nfsd_up = true; 229 nfsd_up = true;
230 return 0; 230 return 0;
231out_lockd: 231out_lockd:
232 lockd_down(); 232 lockd_down(&init_net);
233out_racache: 233out_racache:
234 nfsd_racache_shutdown(); 234 nfsd_racache_shutdown();
235 return ret; 235 return ret;
@@ -246,7 +246,7 @@ static void nfsd_shutdown(void)
246 if (!nfsd_up) 246 if (!nfsd_up)
247 return; 247 return;
248 nfs4_state_shutdown(); 248 nfs4_state_shutdown();
249 lockd_down(); 249 lockd_down(&init_net);
250 nfsd_racache_shutdown(); 250 nfsd_racache_shutdown();
251 nfsd_up = false; 251 nfsd_up = false;
252} 252}
diff --git a/include/linux/lockd/bind.h b/include/linux/lockd/bind.h
index 11a966e5f829..4d24d64578c4 100644
--- a/include/linux/lockd/bind.h
+++ b/include/linux/lockd/bind.h
@@ -54,7 +54,7 @@ extern void nlmclnt_done(struct nlm_host *host);
54 54
55extern int nlmclnt_proc(struct nlm_host *host, int cmd, 55extern int nlmclnt_proc(struct nlm_host *host, int cmd,
56 struct file_lock *fl); 56 struct file_lock *fl);
57extern int lockd_up(void); 57extern int lockd_up(struct net *net);
58extern void lockd_down(void); 58extern void lockd_down(struct net *net);
59 59
60#endif /* LINUX_LOCKD_BIND_H */ 60#endif /* LINUX_LOCKD_BIND_H */