aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4callback.c
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@citi.umich.edu>2009-05-01 22:36:55 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2009-05-03 15:08:56 -0400
commit63e4863fabc6e165a6ca813051305be58966da45 (patch)
treee84b927ca00ce91c8a3a4e93b7f61a0fea315e00 /fs/nfsd/nfs4callback.c
parent3aea09dc9106407d8bc18e593fbffda9ad632844 (diff)
nfsd4: make recall callback an asynchronous rpc
As with the probe, this removes the need for another kthread. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'fs/nfsd/nfs4callback.c')
-rw-r--r--fs/nfsd/nfs4callback.c74
1 files changed, 49 insertions, 25 deletions
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index b88b207d75d9..f4fab69a8c30 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -494,6 +494,49 @@ nfsd4_probe_callback(struct nfs4_client *clp)
494 do_probe_callback(clp); 494 do_probe_callback(clp);
495} 495}
496 496
497static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata)
498{
499 struct nfs4_delegation *dp = calldata;
500 struct nfs4_client *clp = dp->dl_client;
501
502 switch (task->tk_status) {
503 case -EIO:
504 /* Network partition? */
505 atomic_set(&clp->cl_cb_conn.cb_set, 0);
506 warn_no_callback_path(clp, task->tk_status);
507 case -EBADHANDLE:
508 case -NFS4ERR_BAD_STATEID:
509 /* Race: client probably got cb_recall
510 * before open reply granting delegation */
511 break;
512 default:
513 /* success, or error we can't handle */
514 return;
515 }
516 if (dp->dl_retries--) {
517 rpc_delay(task, 2*HZ);
518 task->tk_status = 0;
519 rpc_restart_call(task);
520 } else {
521 atomic_set(&clp->cl_cb_conn.cb_set, 0);
522 warn_no_callback_path(clp, task->tk_status);
523 }
524}
525
526static void nfsd4_cb_recall_release(void *calldata)
527{
528 struct nfs4_delegation *dp = calldata;
529 struct nfs4_client *clp = dp->dl_client;
530
531 nfs4_put_delegation(dp);
532 put_nfs4_client(clp);
533}
534
535static const struct rpc_call_ops nfsd4_cb_recall_ops = {
536 .rpc_call_done = nfsd4_cb_recall_done,
537 .rpc_release = nfsd4_cb_recall_release,
538};
539
497/* 540/*
498 * called with dp->dl_count inc'ed. 541 * called with dp->dl_count inc'ed.
499 */ 542 */
@@ -507,32 +550,13 @@ nfsd4_cb_recall(struct nfs4_delegation *dp)
507 .rpc_argp = dp, 550 .rpc_argp = dp,
508 .rpc_cred = clp->cl_cb_conn.cb_cred 551 .rpc_cred = clp->cl_cb_conn.cb_cred
509 }; 552 };
510 int status = 0; 553 int status;
511 554
512 dp->dl_retries = 1; 555 dp->dl_retries = 1;
513 status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFT); 556 status = rpc_call_async(clnt, &msg, RPC_TASK_SOFT,
514 while (dp->dl_retries--) { 557 &nfsd4_cb_recall_ops, dp);
515 switch (status) { 558 if (status) {
516 case -EIO: 559 put_nfs4_client(clp);
517 /* Network partition? */ 560 nfs4_put_delegation(dp);
518 atomic_set(&clp->cl_cb_conn.cb_set, 0);
519 case -EBADHANDLE:
520 case -NFS4ERR_BAD_STATEID:
521 /* Race: client probably got cb_recall
522 * before open reply granting delegation */
523 break;
524 default:
525 goto out_put_cred;
526 }
527 ssleep(2);
528 status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFT);
529 } 561 }
530out_put_cred:
531 /*
532 * Success or failure, now we're either waiting for lease expiration
533 * or deleg_return.
534 */
535 put_nfs4_client(clp);
536 nfs4_put_delegation(dp);
537 return;
538} 562}