aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4state.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-01-03 03:55:22 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-01-06 14:58:45 -0500
commit433fbe4c8837e3cc2ba6a6374edf28737d01a2e9 (patch)
tree9448a58eafca388efaab5d3653c818fe60a4450d /fs/nfs/nfs4state.c
parent26e976a884be9aa08f8ff906372f25f68df0d948 (diff)
NFSv4: State recovery cleanup
Use wait_on_bit() when waiting for state recovery to complete. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4state.c')
-rw-r--r--fs/nfs/nfs4state.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 41a5f1a8a98..4ebf4df7f19 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -106,11 +106,10 @@ nfs4_alloc_client(struct in_addr *addr)
106 INIT_WORK(&clp->cl_recoverd, nfs4_recover_state, clp); 106 INIT_WORK(&clp->cl_recoverd, nfs4_recover_state, clp);
107 INIT_WORK(&clp->cl_renewd, nfs4_renew_state, clp); 107 INIT_WORK(&clp->cl_renewd, nfs4_renew_state, clp);
108 INIT_LIST_HEAD(&clp->cl_superblocks); 108 INIT_LIST_HEAD(&clp->cl_superblocks);
109 init_waitqueue_head(&clp->cl_waitq);
110 rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client"); 109 rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS4 client");
111 clp->cl_rpcclient = ERR_PTR(-EINVAL); 110 clp->cl_rpcclient = ERR_PTR(-EINVAL);
112 clp->cl_boot_time = CURRENT_TIME; 111 clp->cl_boot_time = CURRENT_TIME;
113 clp->cl_state = 1 << NFS4CLNT_OK; 112 clp->cl_state = 0;
114 return clp; 113 return clp;
115} 114}
116 115
@@ -193,7 +192,6 @@ nfs4_put_client(struct nfs4_client *clp)
193 list_del(&clp->cl_servers); 192 list_del(&clp->cl_servers);
194 spin_unlock(&state_spinlock); 193 spin_unlock(&state_spinlock);
195 BUG_ON(!list_empty(&clp->cl_superblocks)); 194 BUG_ON(!list_empty(&clp->cl_superblocks));
196 wake_up_all(&clp->cl_waitq);
197 rpc_wake_up(&clp->cl_rpcwaitq); 195 rpc_wake_up(&clp->cl_rpcwaitq);
198 nfs4_kill_renewd(clp); 196 nfs4_kill_renewd(clp);
199 nfs4_free_client(clp); 197 nfs4_free_client(clp);
@@ -741,6 +739,15 @@ struct reclaimer_args {
741 struct completion complete; 739 struct completion complete;
742}; 740};
743 741
742static inline void nfs4_clear_recover_bit(struct nfs4_client *clp)
743{
744 smp_mb__before_clear_bit();
745 clear_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state);
746 smp_mb__after_clear_bit();
747 wake_up_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER);
748 rpc_wake_up(&clp->cl_rpcwaitq);
749}
750
744/* 751/*
745 * State recovery routine 752 * State recovery routine
746 */ 753 */
@@ -760,9 +767,7 @@ nfs4_recover_state(void *data)
760 wait_for_completion(&args.complete); 767 wait_for_completion(&args.complete);
761 return; 768 return;
762out_failed_clear: 769out_failed_clear:
763 set_bit(NFS4CLNT_OK, &clp->cl_state); 770 nfs4_clear_recover_bit(clp);
764 wake_up_all(&clp->cl_waitq);
765 rpc_wake_up(&clp->cl_rpcwaitq);
766} 771}
767 772
768/* 773/*
@@ -773,7 +778,7 @@ nfs4_schedule_state_recovery(struct nfs4_client *clp)
773{ 778{
774 if (!clp) 779 if (!clp)
775 return; 780 return;
776 if (test_and_clear_bit(NFS4CLNT_OK, &clp->cl_state)) 781 if (test_and_set_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0)
777 schedule_work(&clp->cl_recoverd); 782 schedule_work(&clp->cl_recoverd);
778} 783}
779 784
@@ -943,13 +948,11 @@ restart_loop:
943 } 948 }
944 nfs_delegation_reap_unclaimed(clp); 949 nfs_delegation_reap_unclaimed(clp);
945out: 950out:
946 set_bit(NFS4CLNT_OK, &clp->cl_state);
947 up_write(&clp->cl_sem); 951 up_write(&clp->cl_sem);
948 unlock_kernel(); 952 unlock_kernel();
949 wake_up_all(&clp->cl_waitq);
950 rpc_wake_up(&clp->cl_rpcwaitq);
951 if (status == -NFS4ERR_CB_PATH_DOWN) 953 if (status == -NFS4ERR_CB_PATH_DOWN)
952 nfs_handle_cb_pathdown(clp); 954 nfs_handle_cb_pathdown(clp);
955 nfs4_clear_recover_bit(clp);
953 nfs4_put_client(clp); 956 nfs4_put_client(clp);
954 return 0; 957 return 0;
955out_error: 958out_error: