diff options
author | J. Bruce Fields <bfields@citi.umich.edu> | 2009-05-01 22:36:55 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2009-05-03 15:08:56 -0400 |
commit | 63e4863fabc6e165a6ca813051305be58966da45 (patch) | |
tree | e84b927ca00ce91c8a3a4e93b7f61a0fea315e00 /fs/nfsd/nfs4callback.c | |
parent | 3aea09dc9106407d8bc18e593fbffda9ad632844 (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.c | 74 |
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 | ||
497 | static 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 | |||
526 | static 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 | |||
535 | static 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 | } |
530 | out_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 | } |