diff options
Diffstat (limited to 'fs/nfs/nfs4state.c')
-rw-r--r-- | fs/nfs/nfs4state.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 41a5f1a8a984..4ebf4df7f191 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 | ||
742 | static 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; |
762 | out_failed_clear: | 769 | out_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); |
945 | out: | 950 | out: |
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; |
955 | out_error: | 958 | out_error: |