aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4callback.c
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@citi.umich.edu>2007-10-25 19:00:26 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2008-02-01 16:42:01 -0500
commit63c86716ea34ad94d52e5b0abbda152574dc42b5 (patch)
treec92ceed9f40f43dc79e099a1f3d4da99d6f985b6 /fs/nfsd/nfs4callback.c
parent46f8a64bae11f5c9b15b4401f6e9863281999b66 (diff)
nfsd: move callback rpc_client creation into separate thread
The whole reason to move this callback-channel probe into a separate thread was because (for now) we don't have an easy way to create the rpc_client asynchronously. But I forgot to move the rpc_create() to the spawned thread. Doh! Fix that. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'fs/nfsd/nfs4callback.c')
-rw-r--r--fs/nfsd/nfs4callback.c78
1 files changed, 39 insertions, 39 deletions
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index a9735a672963..6eb5cd2381ab 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -350,30 +350,6 @@ static struct rpc_version * nfs_cb_version[] = {
350static int do_probe_callback(void *data) 350static int do_probe_callback(void *data)
351{ 351{
352 struct nfs4_client *clp = data; 352 struct nfs4_client *clp = data;
353 struct nfs4_callback *cb = &clp->cl_callback;
354 struct rpc_message msg = {
355 .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
356 .rpc_argp = clp,
357 };
358 int status;
359
360 status = rpc_call_sync(cb->cb_client, &msg, RPC_TASK_SOFT);
361
362 if (status) {
363 rpc_shutdown_client(cb->cb_client);
364 cb->cb_client = NULL;
365 } else
366 atomic_set(&cb->cb_set, 1);
367 put_nfs4_client(clp);
368 return 0;
369}
370
371/*
372 * Set up the callback client and put a NFSPROC4_CB_NULL on the wire...
373 */
374void
375nfsd4_probe_callback(struct nfs4_client *clp)
376{
377 struct sockaddr_in addr; 353 struct sockaddr_in addr;
378 struct nfs4_callback *cb = &clp->cl_callback; 354 struct nfs4_callback *cb = &clp->cl_callback;
379 struct rpc_timeout timeparms = { 355 struct rpc_timeout timeparms = {
@@ -390,12 +366,15 @@ nfsd4_probe_callback(struct nfs4_client *clp)
390 .timeout = &timeparms, 366 .timeout = &timeparms,
391 .program = program, 367 .program = program,
392 .version = nfs_cb_version[1]->number, 368 .version = nfs_cb_version[1]->number,
393 .authflavor = RPC_AUTH_UNIX, /* XXX: need AUTH_GSS... */ 369 .authflavor = RPC_AUTH_UNIX, /* XXX: need AUTH_GSS... */
394 .flags = (RPC_CLNT_CREATE_NOPING), 370 .flags = (RPC_CLNT_CREATE_NOPING),
395 }; 371 };
396 struct task_struct *t; 372 struct rpc_message msg = {
397 373 .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
398 BUG_ON(atomic_read(&clp->cl_callback.cb_set)); 374 .rpc_argp = clp,
375 };
376 struct rpc_clnt *client;
377 int status;
399 378
400 /* Initialize address */ 379 /* Initialize address */
401 memset(&addr, 0, sizeof(addr)); 380 memset(&addr, 0, sizeof(addr));
@@ -415,29 +394,50 @@ nfsd4_probe_callback(struct nfs4_client *clp)
415 program->stats->program = program; 394 program->stats->program = program;
416 395
417 /* Create RPC client */ 396 /* Create RPC client */
418 cb->cb_client = rpc_create(&args); 397 client = rpc_create(&args);
419 if (IS_ERR(cb->cb_client)) { 398 if (IS_ERR(client)) {
420 dprintk("NFSD: couldn't create callback client\n"); 399 dprintk("NFSD: couldn't create callback client\n");
400 status = PTR_ERR(client);
421 goto out_err; 401 goto out_err;
422 } 402 }
423 403
404 status = rpc_call_sync(client, &msg, RPC_TASK_SOFT);
405
406 if (status)
407 goto out_release_client;
408
409 cb->cb_client = client;
410 atomic_set(&cb->cb_set, 1);
411 put_nfs4_client(clp);
412 return 0;
413out_release_client:
414 rpc_shutdown_client(client);
415out_err:
416 put_nfs4_client(clp);
417 dprintk("NFSD: warning: no callback path to client %.*s\n",
418 (int)clp->cl_name.len, clp->cl_name.data);
419 return status;
420}
421
422/*
423 * Set up the callback client and put a NFSPROC4_CB_NULL on the wire...
424 */
425void
426nfsd4_probe_callback(struct nfs4_client *clp)
427{
428 struct task_struct *t;
429
430 BUG_ON(atomic_read(&clp->cl_callback.cb_set));
431
424 /* the task holds a reference to the nfs4_client struct */ 432 /* the task holds a reference to the nfs4_client struct */
425 atomic_inc(&clp->cl_count); 433 atomic_inc(&clp->cl_count);
426 434
427 t = kthread_run(do_probe_callback, clp, "nfs4_cb_probe"); 435 t = kthread_run(do_probe_callback, clp, "nfs4_cb_probe");
428 436
429 if (IS_ERR(t)) 437 if (IS_ERR(t))
430 goto out_release_clp; 438 atomic_dec(&clp->cl_count);
431 439
432 return; 440 return;
433
434out_release_clp:
435 atomic_dec(&clp->cl_count);
436 rpc_shutdown_client(cb->cb_client);
437out_err:
438 cb->cb_client = NULL;
439 dprintk("NFSD: warning: no callback path to client %.*s\n",
440 (int)clp->cl_name.len, clp->cl_name.data);
441} 441}
442 442
443/* 443/*