aboutsummaryrefslogtreecommitdiffstats
path: root/fs/lockd
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-06-01 11:32:58 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-06-01 11:32:58 -0400
commit419f4319495043a9507ac3e616be9ca60af09744 (patch)
tree0f747d80d11a6d4cd726ad6556839d5cd40b23ac /fs/lockd
parentfb21affa49204acd409328415b49bfe90136653c (diff)
parent6eccece90b6addf80ef9e6db79b0bc873301034b (diff)
Merge branch 'for-3.5' of git://linux-nfs.org/~bfields/linux
Pull the rest of the nfsd commits from Bruce Fields: "... and then I cherry-picked the remainder of the patches from the head of my previous branch" This is the rest of the original nfsd branch, rebased without the delegation stuff that I thought really needed to be redone. I don't like rebasing things like this in general, but in this situation this was the lesser of two evils. * 'for-3.5' of git://linux-nfs.org/~bfields/linux: (50 commits) nfsd4: fix, consolidate client_has_state nfsd4: don't remove rebooted client record until confirmation nfsd4: remove some dprintk's and a comment nfsd4: return "real" sequence id in confirmed case nfsd4: fix exchange_id to return confirm flag nfsd4: clarify that renewing expired client is a bug nfsd4: simpler ordering of setclientid_confirm checks nfsd4: setclientid: remove pointless assignment nfsd4: fix error return in non-matching-creds case nfsd4: fix setclientid_confirm same_cred check nfsd4: merge 3 setclientid cases to 2 nfsd4: pull out common code from setclientid cases nfsd4: merge last two setclientid cases nfsd4: setclientid/confirm comment cleanup nfsd4: setclientid remove unnecessary terms from a logical expression nfsd4: move rq_flavor into svc_cred nfsd4: stricter cred comparison for setclientid/exchange_id nfsd4: move principal name into svc_cred nfsd4: allow removing clients not holding state nfsd4: rearrange exchange_id logic to simplify ...
Diffstat (limited to 'fs/lockd')
-rw-r--r--fs/lockd/svc.c145
1 files changed, 90 insertions, 55 deletions
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 1ead0750cdbb..80938fda67e0 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -251,39 +251,40 @@ out_err:
251 return err; 251 return err;
252} 252}
253 253
254static int lockd_up_net(struct net *net) 254static int lockd_up_net(struct svc_serv *serv, struct net *net)
255{ 255{
256 struct lockd_net *ln = net_generic(net, lockd_net_id); 256 struct lockd_net *ln = net_generic(net, lockd_net_id);
257 struct svc_serv *serv = nlmsvc_rqst->rq_server;
258 int error; 257 int error;
259 258
260 if (ln->nlmsvc_users) 259 if (ln->nlmsvc_users++)
261 return 0; 260 return 0;
262 261
263 error = svc_rpcb_setup(serv, net); 262 error = svc_bind(serv, net);
264 if (error) 263 if (error)
265 goto err_rpcb; 264 goto err_bind;
266 265
267 error = make_socks(serv, net); 266 error = make_socks(serv, net);
268 if (error < 0) 267 if (error < 0)
269 goto err_socks; 268 goto err_socks;
269 dprintk("lockd_up_net: per-net data created; net=%p\n", net);
270 return 0; 270 return 0;
271 271
272err_socks: 272err_socks:
273 svc_rpcb_cleanup(serv, net); 273 svc_rpcb_cleanup(serv, net);
274err_rpcb: 274err_bind:
275 ln->nlmsvc_users--;
275 return error; 276 return error;
276} 277}
277 278
278static void lockd_down_net(struct net *net) 279static void lockd_down_net(struct svc_serv *serv, struct net *net)
279{ 280{
280 struct lockd_net *ln = net_generic(net, lockd_net_id); 281 struct lockd_net *ln = net_generic(net, lockd_net_id);
281 struct svc_serv *serv = nlmsvc_rqst->rq_server;
282 282
283 if (ln->nlmsvc_users) { 283 if (ln->nlmsvc_users) {
284 if (--ln->nlmsvc_users == 0) { 284 if (--ln->nlmsvc_users == 0) {
285 nlm_shutdown_hosts_net(net); 285 nlm_shutdown_hosts_net(net);
286 svc_shutdown_net(serv, net); 286 svc_shutdown_net(serv, net);
287 dprintk("lockd_down_net: per-net data destroyed; net=%p\n", net);
287 } 288 }
288 } else { 289 } else {
289 printk(KERN_ERR "lockd_down_net: no users! task=%p, net=%p\n", 290 printk(KERN_ERR "lockd_down_net: no users! task=%p, net=%p\n",
@@ -292,21 +293,60 @@ static void lockd_down_net(struct net *net)
292 } 293 }
293} 294}
294 295
295/* 296static int lockd_start_svc(struct svc_serv *serv)
296 * Bring up the lockd process if it's not already up. 297{
297 */ 298 int error;
298int lockd_up(struct net *net) 299
300 if (nlmsvc_rqst)
301 return 0;
302
303 /*
304 * Create the kernel thread and wait for it to start.
305 */
306 nlmsvc_rqst = svc_prepare_thread(serv, &serv->sv_pools[0], NUMA_NO_NODE);
307 if (IS_ERR(nlmsvc_rqst)) {
308 error = PTR_ERR(nlmsvc_rqst);
309 printk(KERN_WARNING
310 "lockd_up: svc_rqst allocation failed, error=%d\n",
311 error);
312 goto out_rqst;
313 }
314
315 svc_sock_update_bufs(serv);
316 serv->sv_maxconn = nlm_max_connections;
317
318 nlmsvc_task = kthread_run(lockd, nlmsvc_rqst, serv->sv_name);
319 if (IS_ERR(nlmsvc_task)) {
320 error = PTR_ERR(nlmsvc_task);
321 printk(KERN_WARNING
322 "lockd_up: kthread_run failed, error=%d\n", error);
323 goto out_task;
324 }
325 dprintk("lockd_up: service started\n");
326 return 0;
327
328out_task:
329 svc_exit_thread(nlmsvc_rqst);
330 nlmsvc_task = NULL;
331out_rqst:
332 nlmsvc_rqst = NULL;
333 return error;
334}
335
336static struct svc_serv *lockd_create_svc(void)
299{ 337{
300 struct svc_serv *serv; 338 struct svc_serv *serv;
301 int error = 0;
302 339
303 mutex_lock(&nlmsvc_mutex);
304 /* 340 /*
305 * Check whether we're already up and running. 341 * Check whether we're already up and running.
306 */ 342 */
307 if (nlmsvc_rqst) { 343 if (nlmsvc_rqst) {
308 error = lockd_up_net(net); 344 /*
309 goto out; 345 * Note: increase service usage, because later in case of error
346 * svc_destroy() will be called.
347 */
348 svc_get(nlmsvc_rqst->rq_server);
349 return nlmsvc_rqst->rq_server;
310 } 350 }
311 351
312 /* 352 /*
@@ -317,59 +357,53 @@ int lockd_up(struct net *net)
317 printk(KERN_WARNING 357 printk(KERN_WARNING
318 "lockd_up: no pid, %d users??\n", nlmsvc_users); 358 "lockd_up: no pid, %d users??\n", nlmsvc_users);
319 359
320 error = -ENOMEM;
321 serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL); 360 serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL);
322 if (!serv) { 361 if (!serv) {
323 printk(KERN_WARNING "lockd_up: create service failed\n"); 362 printk(KERN_WARNING "lockd_up: create service failed\n");
324 goto out; 363 return ERR_PTR(-ENOMEM);
325 } 364 }
365 dprintk("lockd_up: service created\n");
366 return serv;
367}
326 368
327 error = make_socks(serv, net); 369/*
328 if (error < 0) 370 * Bring up the lockd process if it's not already up.
329 goto destroy_and_out; 371 */
372int lockd_up(struct net *net)
373{
374 struct svc_serv *serv;
375 int error;
330 376
331 /* 377 mutex_lock(&nlmsvc_mutex);
332 * Create the kernel thread and wait for it to start. 378
333 */ 379 serv = lockd_create_svc();
334 nlmsvc_rqst = svc_prepare_thread(serv, &serv->sv_pools[0], NUMA_NO_NODE); 380 if (IS_ERR(serv)) {
335 if (IS_ERR(nlmsvc_rqst)) { 381 error = PTR_ERR(serv);
336 error = PTR_ERR(nlmsvc_rqst); 382 goto err_create;
337 nlmsvc_rqst = NULL;
338 printk(KERN_WARNING
339 "lockd_up: svc_rqst allocation failed, error=%d\n",
340 error);
341 goto destroy_and_out;
342 } 383 }
343 384
344 svc_sock_update_bufs(serv); 385 error = lockd_up_net(serv, net);
345 serv->sv_maxconn = nlm_max_connections; 386 if (error < 0)
387 goto err_net;
346 388
347 nlmsvc_task = kthread_run(lockd, nlmsvc_rqst, serv->sv_name); 389 error = lockd_start_svc(serv);
348 if (IS_ERR(nlmsvc_task)) { 390 if (error < 0)
349 error = PTR_ERR(nlmsvc_task); 391 goto err_start;
350 svc_exit_thread(nlmsvc_rqst);
351 nlmsvc_task = NULL;
352 nlmsvc_rqst = NULL;
353 printk(KERN_WARNING
354 "lockd_up: kthread_run failed, error=%d\n", error);
355 goto destroy_and_out;
356 }
357 392
393 nlmsvc_users++;
358 /* 394 /*
359 * Note: svc_serv structures have an initial use count of 1, 395 * Note: svc_serv structures have an initial use count of 1,
360 * so we exit through here on both success and failure. 396 * so we exit through here on both success and failure.
361 */ 397 */
362destroy_and_out: 398err_net:
363 svc_destroy(serv); 399 svc_destroy(serv);
364out: 400err_create:
365 if (!error) {
366 struct lockd_net *ln = net_generic(net, lockd_net_id);
367
368 ln->nlmsvc_users++;
369 nlmsvc_users++;
370 }
371 mutex_unlock(&nlmsvc_mutex); 401 mutex_unlock(&nlmsvc_mutex);
372 return error; 402 return error;
403
404err_start:
405 lockd_down_net(serv, net);
406 goto err_net;
373} 407}
374EXPORT_SYMBOL_GPL(lockd_up); 408EXPORT_SYMBOL_GPL(lockd_up);
375 409
@@ -380,11 +414,10 @@ void
380lockd_down(struct net *net) 414lockd_down(struct net *net)
381{ 415{
382 mutex_lock(&nlmsvc_mutex); 416 mutex_lock(&nlmsvc_mutex);
417 lockd_down_net(nlmsvc_rqst->rq_server, net);
383 if (nlmsvc_users) { 418 if (nlmsvc_users) {
384 if (--nlmsvc_users) { 419 if (--nlmsvc_users)
385 lockd_down_net(net);
386 goto out; 420 goto out;
387 }
388 } else { 421 } else {
389 printk(KERN_ERR "lockd_down: no users! task=%p\n", 422 printk(KERN_ERR "lockd_down: no users! task=%p\n",
390 nlmsvc_task); 423 nlmsvc_task);
@@ -396,7 +429,9 @@ lockd_down(struct net *net)
396 BUG(); 429 BUG();
397 } 430 }
398 kthread_stop(nlmsvc_task); 431 kthread_stop(nlmsvc_task);
432 dprintk("lockd_down: service stopped\n");
399 svc_exit_thread(nlmsvc_rqst); 433 svc_exit_thread(nlmsvc_rqst);
434 dprintk("lockd_down: service destroyed\n");
400 nlmsvc_task = NULL; 435 nlmsvc_task = NULL;
401 nlmsvc_rqst = NULL; 436 nlmsvc_rqst = NULL;
402out: 437out: