aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-11-04 15:27:43 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-11-04 15:27:43 -0400
commit6736c047995c560b73f3860095c631456b0bbea8 (patch)
tree1ef4d2ab9d7d2f2cd3fe26a3e9135fb312e81b85 /net
parent16dfd1faed8c5235d9a7c190b91b6d97d6cd3272 (diff)
parent6070295efc90d1093b2031c43380bd7d9673c802 (diff)
Merge branch 'nfs-for-3.2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
* 'nfs-for-3.2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (25 commits) nfs: set vs_hidden on nfs4_callback_version4 (try #2) pnfs-obj: Support for RAID5 read-4-write interface. pnfs-obj: move to ore 03: Remove old raid engine pnfs-obj: move to ore 02: move to ORE pnfs-obj: move to ore 01: ore_layout & ore_components pnfs-obj: Rename objlayout_io_state => objlayout_io_res pnfs-obj: Get rid of objlayout_{alloc,free}_io_state pnfs-obj: Return PNFS_NOT_ATTEMPTED in case of read/write_pagelist pnfs-obj: Remove redundant EOF from objlayout_io_state nfs: Remove unused variable from write.c nfs: Fix unused variable warning from file.c NFS: Remove no-op less-than-zero checks on unsigned variables. NFS: Clean up nfs4_xdr_dec_secinfo() NFS: Fix documenting comment for nfs_create_request() NFS4: fix cb_recallany decode error nfs4: serialize layoutcommit SUNRPC: remove rpcbind clients destruction on module cleanup SUNRPC: remove rpcbind clients creation during service registering NFSd: call svc rpcbind cleanup explicitly SUNRPC: cleanup service destruction ...
Diffstat (limited to 'net')
-rw-r--r--net/sunrpc/auth_unix.c3
-rw-r--r--net/sunrpc/rpcb_clnt.c88
-rw-r--r--net/sunrpc/sunrpc_syms.c3
-rw-r--r--net/sunrpc/svc.c48
4 files changed, 106 insertions, 36 deletions
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c
index 4cb70dc6e7ad..e50502d8ceb7 100644
--- a/net/sunrpc/auth_unix.c
+++ b/net/sunrpc/auth_unix.c
@@ -129,6 +129,9 @@ unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
129 for (i = 0; i < groups ; i++) 129 for (i = 0; i < groups ; i++)
130 if (cred->uc_gids[i] != GROUP_AT(acred->group_info, i)) 130 if (cred->uc_gids[i] != GROUP_AT(acred->group_info, i))
131 return 0; 131 return 0;
132 if (groups < NFS_NGROUPS &&
133 cred->uc_gids[groups] != NOGROUP)
134 return 0;
132 return 1; 135 return 1;
133} 136}
134 137
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index f588b852d41c..8761bf8e36fc 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -114,6 +114,9 @@ static struct rpc_program rpcb_program;
114static struct rpc_clnt * rpcb_local_clnt; 114static struct rpc_clnt * rpcb_local_clnt;
115static struct rpc_clnt * rpcb_local_clnt4; 115static struct rpc_clnt * rpcb_local_clnt4;
116 116
117DEFINE_SPINLOCK(rpcb_clnt_lock);
118unsigned int rpcb_users;
119
117struct rpcbind_args { 120struct rpcbind_args {
118 struct rpc_xprt * r_xprt; 121 struct rpc_xprt * r_xprt;
119 122
@@ -161,6 +164,56 @@ static void rpcb_map_release(void *data)
161 kfree(map); 164 kfree(map);
162} 165}
163 166
167static int rpcb_get_local(void)
168{
169 int cnt;
170
171 spin_lock(&rpcb_clnt_lock);
172 if (rpcb_users)
173 rpcb_users++;
174 cnt = rpcb_users;
175 spin_unlock(&rpcb_clnt_lock);
176
177 return cnt;
178}
179
180void rpcb_put_local(void)
181{
182 struct rpc_clnt *clnt = rpcb_local_clnt;
183 struct rpc_clnt *clnt4 = rpcb_local_clnt4;
184 int shutdown;
185
186 spin_lock(&rpcb_clnt_lock);
187 if (--rpcb_users == 0) {
188 rpcb_local_clnt = NULL;
189 rpcb_local_clnt4 = NULL;
190 }
191 shutdown = !rpcb_users;
192 spin_unlock(&rpcb_clnt_lock);
193
194 if (shutdown) {
195 /*
196 * cleanup_rpcb_clnt - remove xprtsock's sysctls, unregister
197 */
198 if (clnt4)
199 rpc_shutdown_client(clnt4);
200 if (clnt)
201 rpc_shutdown_client(clnt);
202 }
203}
204
205static void rpcb_set_local(struct rpc_clnt *clnt, struct rpc_clnt *clnt4)
206{
207 /* Protected by rpcb_create_local_mutex */
208 rpcb_local_clnt = clnt;
209 rpcb_local_clnt4 = clnt4;
210 smp_wmb();
211 rpcb_users = 1;
212 dprintk("RPC: created new rpcb local clients (rpcb_local_clnt: "
213 "%p, rpcb_local_clnt4: %p)\n", rpcb_local_clnt,
214 rpcb_local_clnt4);
215}
216
164/* 217/*
165 * Returns zero on success, otherwise a negative errno value 218 * Returns zero on success, otherwise a negative errno value
166 * is returned. 219 * is returned.
@@ -205,9 +258,7 @@ static int rpcb_create_local_unix(void)
205 clnt4 = NULL; 258 clnt4 = NULL;
206 } 259 }
207 260
208 /* Protected by rpcb_create_local_mutex */ 261 rpcb_set_local(clnt, clnt4);
209 rpcb_local_clnt = clnt;
210 rpcb_local_clnt4 = clnt4;
211 262
212out: 263out:
213 return result; 264 return result;
@@ -259,9 +310,7 @@ static int rpcb_create_local_net(void)
259 clnt4 = NULL; 310 clnt4 = NULL;
260 } 311 }
261 312
262 /* Protected by rpcb_create_local_mutex */ 313 rpcb_set_local(clnt, clnt4);
263 rpcb_local_clnt = clnt;
264 rpcb_local_clnt4 = clnt4;
265 314
266out: 315out:
267 return result; 316 return result;
@@ -271,16 +320,16 @@ out:
271 * Returns zero on success, otherwise a negative errno value 320 * Returns zero on success, otherwise a negative errno value
272 * is returned. 321 * is returned.
273 */ 322 */
274static int rpcb_create_local(void) 323int rpcb_create_local(void)
275{ 324{
276 static DEFINE_MUTEX(rpcb_create_local_mutex); 325 static DEFINE_MUTEX(rpcb_create_local_mutex);
277 int result = 0; 326 int result = 0;
278 327
279 if (rpcb_local_clnt) 328 if (rpcb_get_local())
280 return result; 329 return result;
281 330
282 mutex_lock(&rpcb_create_local_mutex); 331 mutex_lock(&rpcb_create_local_mutex);
283 if (rpcb_local_clnt) 332 if (rpcb_get_local())
284 goto out; 333 goto out;
285 334
286 if (rpcb_create_local_unix() != 0) 335 if (rpcb_create_local_unix() != 0)
@@ -382,11 +431,6 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
382 struct rpc_message msg = { 431 struct rpc_message msg = {
383 .rpc_argp = &map, 432 .rpc_argp = &map,
384 }; 433 };
385 int error;
386
387 error = rpcb_create_local();
388 if (error)
389 return error;
390 434
391 dprintk("RPC: %sregistering (%u, %u, %d, %u) with local " 435 dprintk("RPC: %sregistering (%u, %u, %d, %u) with local "
392 "rpcbind\n", (port ? "" : "un"), 436 "rpcbind\n", (port ? "" : "un"),
@@ -522,11 +566,7 @@ int rpcb_v4_register(const u32 program, const u32 version,
522 struct rpc_message msg = { 566 struct rpc_message msg = {
523 .rpc_argp = &map, 567 .rpc_argp = &map,
524 }; 568 };
525 int error;
526 569
527 error = rpcb_create_local();
528 if (error)
529 return error;
530 if (rpcb_local_clnt4 == NULL) 570 if (rpcb_local_clnt4 == NULL)
531 return -EPROTONOSUPPORT; 571 return -EPROTONOSUPPORT;
532 572
@@ -1060,15 +1100,3 @@ static struct rpc_program rpcb_program = {
1060 .version = rpcb_version, 1100 .version = rpcb_version,
1061 .stats = &rpcb_stats, 1101 .stats = &rpcb_stats,
1062}; 1102};
1063
1064/**
1065 * cleanup_rpcb_clnt - remove xprtsock's sysctls, unregister
1066 *
1067 */
1068void cleanup_rpcb_clnt(void)
1069{
1070 if (rpcb_local_clnt4)
1071 rpc_shutdown_client(rpcb_local_clnt4);
1072 if (rpcb_local_clnt)
1073 rpc_shutdown_client(rpcb_local_clnt);
1074}
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index 9d0809160994..8ec9778c3f4a 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -61,8 +61,6 @@ static struct pernet_operations sunrpc_net_ops = {
61 61
62extern struct cache_detail unix_gid_cache; 62extern struct cache_detail unix_gid_cache;
63 63
64extern void cleanup_rpcb_clnt(void);
65
66static int __init 64static int __init
67init_sunrpc(void) 65init_sunrpc(void)
68{ 66{
@@ -102,7 +100,6 @@ out:
102static void __exit 100static void __exit
103cleanup_sunrpc(void) 101cleanup_sunrpc(void)
104{ 102{
105 cleanup_rpcb_clnt();
106 rpcauth_remove_module(); 103 rpcauth_remove_module();
107 cleanup_socket_xprt(); 104 cleanup_socket_xprt();
108 svc_cleanup_xprt_sock(); 105 svc_cleanup_xprt_sock();
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index dd5cc00ed559..6e038884ae0c 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -366,6 +366,42 @@ svc_pool_for_cpu(struct svc_serv *serv, int cpu)
366 return &serv->sv_pools[pidx % serv->sv_nrpools]; 366 return &serv->sv_pools[pidx % serv->sv_nrpools];
367} 367}
368 368
369static int svc_rpcb_setup(struct svc_serv *serv)
370{
371 int err;
372
373 err = rpcb_create_local();
374 if (err)
375 return err;
376
377 /* Remove any stale portmap registrations */
378 svc_unregister(serv);
379 return 0;
380}
381
382void svc_rpcb_cleanup(struct svc_serv *serv)
383{
384 svc_unregister(serv);
385 rpcb_put_local();
386}
387EXPORT_SYMBOL_GPL(svc_rpcb_cleanup);
388
389static int svc_uses_rpcbind(struct svc_serv *serv)
390{
391 struct svc_program *progp;
392 unsigned int i;
393
394 for (progp = serv->sv_program; progp; progp = progp->pg_next) {
395 for (i = 0; i < progp->pg_nvers; i++) {
396 if (progp->pg_vers[i] == NULL)
397 continue;
398 if (progp->pg_vers[i]->vs_hidden == 0)
399 return 1;
400 }
401 }
402
403 return 0;
404}
369 405
370/* 406/*
371 * Create an RPC service 407 * Create an RPC service
@@ -431,8 +467,15 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
431 spin_lock_init(&pool->sp_lock); 467 spin_lock_init(&pool->sp_lock);
432 } 468 }
433 469
434 /* Remove any stale portmap registrations */ 470 if (svc_uses_rpcbind(serv)) {
435 svc_unregister(serv); 471 if (svc_rpcb_setup(serv) < 0) {
472 kfree(serv->sv_pools);
473 kfree(serv);
474 return NULL;
475 }
476 if (!serv->sv_shutdown)
477 serv->sv_shutdown = svc_rpcb_cleanup;
478 }
436 479
437 return serv; 480 return serv;
438} 481}
@@ -500,7 +543,6 @@ svc_destroy(struct svc_serv *serv)
500 if (svc_serv_is_pooled(serv)) 543 if (svc_serv_is_pooled(serv))
501 svc_pool_map_put(); 544 svc_pool_map_put();
502 545
503 svc_unregister(serv);
504 kfree(serv->sv_pools); 546 kfree(serv->sv_pools);
505 kfree(serv); 547 kfree(serv);
506} 548}