aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@citi.umich.edu>2009-02-23 22:35:22 -0500
committerJ. Bruce Fields <bfields@citi.umich.edu>2009-04-29 16:44:53 -0400
commitecdd03b7914c91ef849e49c4d466c87f4981b5cd (patch)
tree16d67b4af0e8545f60e31f0b1f9cfb0f97526641 /fs
parente1cab5a5896e142190cd66a8287099b52e5855a7 (diff)
nfsd4: create rpc callback client from server thread
The code is a little simpler, and it should be easier to avoid races, if we just do all rpc client creation/destruction from nfsd or laundromat threads and do only the rpc calls themselves asynchronously. The rpc creation doesn't involve any significant waiting (it doesn't call the client, for example), so there's no reason not to do this. Also don't bother destroying the client on failure of the rpc null probe. We may want to retry the probe later anyway. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfsd/nfs4callback.c31
1 files changed, 16 insertions, 15 deletions
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 4788d09d9bec..711c6282151f 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -409,6 +409,12 @@ int setup_callback_client(struct nfs4_client *clp)
409 409
410} 410}
411 411
412static void warn_no_callback_path(struct nfs4_client *clp, int reason)
413{
414 dprintk("NFSD: warning: no callback path to client %.*s: error %d\n",
415 (int)clp->cl_name.len, clp->cl_name.data, reason);
416}
417
412static int do_probe_callback(void *data) 418static int do_probe_callback(void *data)
413{ 419{
414 struct nfs4_client *clp = data; 420 struct nfs4_client *clp = data;
@@ -419,24 +425,12 @@ static int do_probe_callback(void *data)
419 }; 425 };
420 int status; 426 int status;
421 427
422 status = setup_callback_client(clp);
423 if (status)
424 goto out_err;
425
426 status = rpc_call_sync(cb->cb_client, &msg, RPC_TASK_SOFT); 428 status = rpc_call_sync(cb->cb_client, &msg, RPC_TASK_SOFT);
427
428 if (status) 429 if (status)
429 goto out_release_client; 430 warn_no_callback_path(clp, status);
431 else
432 atomic_set(&cb->cb_set, 1);
430 433
431 atomic_set(&cb->cb_set, 1);
432 put_nfs4_client(clp);
433 return 0;
434out_release_client:
435 rpc_shutdown_client(cb->cb_client);
436 cb->cb_client = NULL;
437out_err:
438 dprintk("NFSD: warning: no callback path to client %.*s: error %d\n",
439 (int)clp->cl_name.len, clp->cl_name.data, status);
440 put_nfs4_client(clp); 434 put_nfs4_client(clp);
441 return 0; 435 return 0;
442} 436}
@@ -448,9 +442,16 @@ void
448nfsd4_probe_callback(struct nfs4_client *clp) 442nfsd4_probe_callback(struct nfs4_client *clp)
449{ 443{
450 struct task_struct *t; 444 struct task_struct *t;
445 int status;
451 446
452 BUG_ON(atomic_read(&clp->cl_callback.cb_set)); 447 BUG_ON(atomic_read(&clp->cl_callback.cb_set));
453 448
449 status = setup_callback_client(clp);
450 if (status) {
451 warn_no_callback_path(clp, status);
452 return;
453 }
454
454 /* the task holds a reference to the nfs4_client struct */ 455 /* the task holds a reference to the nfs4_client struct */
455 atomic_inc(&clp->cl_count); 456 atomic_inc(&clp->cl_count);
456 457