aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@citi.umich.edu>2007-11-23 22:26:18 -0500
committerJ. Bruce Fields <bfields@citi.umich.edu>2008-02-01 16:42:06 -0500
commit404ec117be5d36e1a4c4582d0c518594333e32df (patch)
treecdae7b67f896c93130a6a669ca65cffc94079b07
parent35bba9a37e68c68a820a1a772f016255c0838f79 (diff)
nfsd4: recognize callback channel failure earlier
When the callback channel fails, we inform the client of that by returning a cb_path_down error the next time it tries to renew its lease. If we wait most of a lease period before deciding that a callback has failed and that the callback channel is down, then we decrease the chances that the client will find out in time to do anything about it. So, mark the channel down as soon as we recognize that an rpc has failed. However, continue trying to recall delegations anyway, in hopes it will come back up. This will prevent more delegations from being given out, and ensure cb_path_down is returned to renew calls earlier, while still making the best effort to deliver recalls of existing delegations. Also fix a couple comments and remove a dprink that doesn't seem likely to be useful. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
-rw-r--r--fs/nfsd/nfs4callback.c13
-rw-r--r--fs/nfsd/nfs4state.c5
2 files changed, 9 insertions, 9 deletions
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 6eb5cd2381ab..aae2b29ae2c9 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -457,9 +457,6 @@ nfsd4_cb_recall(struct nfs4_delegation *dp)
457 int retries = 1; 457 int retries = 1;
458 int status = 0; 458 int status = 0;
459 459
460 if ((!atomic_read(&clp->cl_callback.cb_set)) || !clnt)
461 return;
462
463 cbr->cbr_trunc = 0; /* XXX need to implement truncate optimization */ 460 cbr->cbr_trunc = 0; /* XXX need to implement truncate optimization */
464 cbr->cbr_dp = dp; 461 cbr->cbr_dp = dp;
465 462
@@ -468,6 +465,7 @@ nfsd4_cb_recall(struct nfs4_delegation *dp)
468 switch (status) { 465 switch (status) {
469 case -EIO: 466 case -EIO:
470 /* Network partition? */ 467 /* Network partition? */
468 atomic_set(&clp->cl_callback.cb_set, 0);
471 case -EBADHANDLE: 469 case -EBADHANDLE:
472 case -NFS4ERR_BAD_STATEID: 470 case -NFS4ERR_BAD_STATEID:
473 /* Race: client probably got cb_recall 471 /* Race: client probably got cb_recall
@@ -480,11 +478,10 @@ nfsd4_cb_recall(struct nfs4_delegation *dp)
480 status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFT); 478 status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFT);
481 } 479 }
482out_put_cred: 480out_put_cred:
483 if (status == -EIO) 481 /*
484 atomic_set(&clp->cl_callback.cb_set, 0); 482 * Success or failure, now we're either waiting for lease expiration
485 /* Success or failure, now we're either waiting for lease expiration 483 * or deleg_return.
486 * or deleg_return. */ 484 */
487 dprintk("NFSD: nfs4_cb_recall: dp %p dl_flock %p dl_count %d\n",dp, dp->dl_flock, atomic_read(&dp->dl_count));
488 put_nfs4_client(clp); 485 put_nfs4_client(clp);
489 nfs4_put_delegation(dp); 486 nfs4_put_delegation(dp);
490 return; 487 return;
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index b9d395856b3a..11aa4b6b4fa2 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -361,8 +361,11 @@ shutdown_callback_client(struct nfs4_client *clp)
361{ 361{
362 struct rpc_clnt *clnt = clp->cl_callback.cb_client; 362 struct rpc_clnt *clnt = clp->cl_callback.cb_client;
363 363
364 /* shutdown rpc client, ending any outstanding recall rpcs */
365 if (clnt) { 364 if (clnt) {
365 /*
366 * Callback threads take a reference on the client, so there
367 * should be no outstanding callbacks at this point.
368 */
366 clp->cl_callback.cb_client = NULL; 369 clp->cl_callback.cb_client = NULL;
367 rpc_shutdown_client(clnt); 370 rpc_shutdown_client(clnt);
368 } 371 }