aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4callback.c
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@citi.umich.edu>2010-04-30 18:51:44 -0400
committerJ. Bruce Fields <bfields@redhat.com>2011-01-11 15:04:10 -0500
commit77a3569d6c4e14e89fa628df383b6dccc0cce6be (patch)
tree3e89bd0aa2fe679ec212212bc232651f08ef7b2b /fs/nfsd/nfs4callback.c
parentf0418aa4b1103f959d64dc18273efa04ee0140e9 (diff)
nfsd4: keep finer-grained callback status
Distinguish between when the callback channel is known to be down, and when it is not yet confirmed. This will be useful in the 4.1 case. Also, we don't seem to be using the fact that this field is atomic. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'fs/nfsd/nfs4callback.c')
-rw-r--r--fs/nfsd/nfs4callback.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 18b740bd29ac..d32f49d6ca2c 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -470,8 +470,6 @@ static int max_cb_time(void)
470 return max(nfsd4_lease/10, (time_t)1) * HZ; 470 return max(nfsd4_lease/10, (time_t)1) * HZ;
471} 471}
472 472
473/* Reference counting, callback cleanup, etc., all look racy as heck.
474 * And why is cl_cb_set an atomic? */
475 473
476static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn, struct nfsd4_session *ses) 474static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn, struct nfsd4_session *ses)
477{ 475{
@@ -526,14 +524,20 @@ static void warn_no_callback_path(struct nfs4_client *clp, int reason)
526 (int)clp->cl_name.len, clp->cl_name.data, reason); 524 (int)clp->cl_name.len, clp->cl_name.data, reason);
527} 525}
528 526
527static void nfsd4_mark_cb_down(struct nfs4_client *clp, int reason)
528{
529 clp->cl_cb_state = NFSD4_CB_DOWN;
530 warn_no_callback_path(clp, reason);
531}
532
529static void nfsd4_cb_probe_done(struct rpc_task *task, void *calldata) 533static void nfsd4_cb_probe_done(struct rpc_task *task, void *calldata)
530{ 534{
531 struct nfs4_client *clp = container_of(calldata, struct nfs4_client, cl_cb_null); 535 struct nfs4_client *clp = container_of(calldata, struct nfs4_client, cl_cb_null);
532 536
533 if (task->tk_status) 537 if (task->tk_status)
534 warn_no_callback_path(clp, task->tk_status); 538 nfsd4_mark_cb_down(clp, task->tk_status);
535 else 539 else
536 atomic_set(&clp->cl_cb_set, 1); 540 clp->cl_cb_state = NFSD4_CB_UP;
537} 541}
538 542
539static const struct rpc_call_ops nfsd4_cb_probe_ops = { 543static const struct rpc_call_ops nfsd4_cb_probe_ops = {
@@ -579,14 +583,15 @@ static void do_probe_callback(struct nfs4_client *clp)
579 */ 583 */
580void nfsd4_probe_callback(struct nfs4_client *clp) 584void nfsd4_probe_callback(struct nfs4_client *clp)
581{ 585{
586 /* XXX: atomicity? Also, should we be using cl_cb_flags? */
587 clp->cl_cb_state = NFSD4_CB_UNKNOWN;
582 set_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_cb_flags); 588 set_bit(NFSD4_CLIENT_CB_UPDATE, &clp->cl_cb_flags);
583 do_probe_callback(clp); 589 do_probe_callback(clp);
584} 590}
585 591
586void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *conn) 592void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *conn)
587{ 593{
588 BUG_ON(atomic_read(&clp->cl_cb_set)); 594 clp->cl_cb_state = NFSD4_CB_UNKNOWN;
589
590 spin_lock(&clp->cl_lock); 595 spin_lock(&clp->cl_lock);
591 memcpy(&clp->cl_cb_conn, conn, sizeof(struct nfs4_cb_conn)); 596 memcpy(&clp->cl_cb_conn, conn, sizeof(struct nfs4_cb_conn));
592 spin_unlock(&clp->cl_lock); 597 spin_unlock(&clp->cl_lock);
@@ -693,8 +698,7 @@ static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata)
693 break; 698 break;
694 default: 699 default:
695 /* Network partition? */ 700 /* Network partition? */
696 atomic_set(&clp->cl_cb_set, 0); 701 nfsd4_mark_cb_down(clp, task->tk_status);
697 warn_no_callback_path(clp, task->tk_status);
698 if (current_rpc_client != task->tk_client) { 702 if (current_rpc_client != task->tk_client) {
699 /* queue a callback on the new connection: */ 703 /* queue a callback on the new connection: */
700 atomic_inc(&dp->dl_count); 704 atomic_inc(&dp->dl_count);
@@ -707,10 +711,8 @@ static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata)
707 task->tk_status = 0; 711 task->tk_status = 0;
708 rpc_restart_call_prepare(task); 712 rpc_restart_call_prepare(task);
709 return; 713 return;
710 } else { 714 } else
711 atomic_set(&clp->cl_cb_set, 0); 715 nfsd4_mark_cb_down(clp, task->tk_status);
712 warn_no_callback_path(clp, task->tk_status);
713 }
714} 716}
715 717
716static void nfsd4_cb_recall_release(void *calldata) 718static void nfsd4_cb_recall_release(void *calldata)