diff options
-rw-r--r-- | fs/nfs/delegation.c | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4_fs.h | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 4 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 49 |
4 files changed, 32 insertions, 25 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index ff2c1585d23f..4692fdc8abf3 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
@@ -360,7 +360,7 @@ static int nfs_do_expire_all_delegations(void *ptr) | |||
360 | 360 | ||
361 | allow_signal(SIGKILL); | 361 | allow_signal(SIGKILL); |
362 | 362 | ||
363 | if (test_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) != 0) | 363 | if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0) |
364 | goto out; | 364 | goto out; |
365 | if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) | 365 | if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) |
366 | goto out; | 366 | goto out; |
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 84a4f5223f61..b7a12e7c6604 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h | |||
@@ -38,7 +38,7 @@ struct idmap; | |||
38 | ((err) != NFSERR_NOFILEHANDLE)) | 38 | ((err) != NFSERR_NOFILEHANDLE)) |
39 | 39 | ||
40 | enum nfs4_client_state { | 40 | enum nfs4_client_state { |
41 | NFS4CLNT_STATE_RECOVER = 0, | 41 | NFS4CLNT_MANAGER_RUNNING = 0, |
42 | NFS4CLNT_CHECK_LEASE, | 42 | NFS4CLNT_CHECK_LEASE, |
43 | NFS4CLNT_LEASE_EXPIRED, | 43 | NFS4CLNT_LEASE_EXPIRED, |
44 | NFS4CLNT_RECLAIM_REBOOT, | 44 | NFS4CLNT_RECLAIM_REBOOT, |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 8a2dee9caa6e..2a347d47e38c 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -207,7 +207,7 @@ static int nfs4_wait_clnt_recover(struct nfs_client *clp) | |||
207 | 207 | ||
208 | might_sleep(); | 208 | might_sleep(); |
209 | 209 | ||
210 | res = wait_on_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER, | 210 | res = wait_on_bit(&clp->cl_state, NFS4CLNT_MANAGER_RUNNING, |
211 | nfs4_wait_bit_killable, TASK_KILLABLE); | 211 | nfs4_wait_bit_killable, TASK_KILLABLE); |
212 | return res; | 212 | return res; |
213 | } | 213 | } |
@@ -2861,7 +2861,7 @@ nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, | |||
2861 | case -NFS4ERR_EXPIRED: | 2861 | case -NFS4ERR_EXPIRED: |
2862 | rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL); | 2862 | rpc_sleep_on(&clp->cl_rpcwaitq, task, NULL); |
2863 | nfs4_schedule_state_recovery(clp); | 2863 | nfs4_schedule_state_recovery(clp); |
2864 | if (test_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0) | 2864 | if (test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) == 0) |
2865 | rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task); | 2865 | rpc_wake_up_queued_task(&clp->cl_rpcwaitq, task); |
2866 | task->tk_status = 0; | 2866 | task->tk_status = 0; |
2867 | return -EAGAIN; | 2867 | return -EAGAIN; |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 2894502b94dc..83f3dd39ac55 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -767,32 +767,34 @@ unlock: | |||
767 | return status; | 767 | return status; |
768 | } | 768 | } |
769 | 769 | ||
770 | static int reclaimer(void *); | 770 | static int nfs4_run_state_manager(void *); |
771 | 771 | ||
772 | static inline void nfs4_clear_recover_bit(struct nfs_client *clp) | 772 | static void nfs4_clear_state_manager_bit(struct nfs_client *clp) |
773 | { | 773 | { |
774 | smp_mb__before_clear_bit(); | 774 | smp_mb__before_clear_bit(); |
775 | clear_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state); | 775 | clear_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state); |
776 | smp_mb__after_clear_bit(); | 776 | smp_mb__after_clear_bit(); |
777 | wake_up_bit(&clp->cl_state, NFS4CLNT_STATE_RECOVER); | 777 | wake_up_bit(&clp->cl_state, NFS4CLNT_MANAGER_RUNNING); |
778 | rpc_wake_up(&clp->cl_rpcwaitq); | 778 | rpc_wake_up(&clp->cl_rpcwaitq); |
779 | } | 779 | } |
780 | 780 | ||
781 | /* | 781 | /* |
782 | * State recovery routine | 782 | * Schedule the nfs_client asynchronous state management routine |
783 | */ | 783 | */ |
784 | static void nfs4_recover_state(struct nfs_client *clp) | 784 | static void nfs4_schedule_state_manager(struct nfs_client *clp) |
785 | { | 785 | { |
786 | struct task_struct *task; | 786 | struct task_struct *task; |
787 | 787 | ||
788 | if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0) | ||
789 | return; | ||
788 | __module_get(THIS_MODULE); | 790 | __module_get(THIS_MODULE); |
789 | atomic_inc(&clp->cl_count); | 791 | atomic_inc(&clp->cl_count); |
790 | task = kthread_run(reclaimer, clp, "%s-reclaim", | 792 | task = kthread_run(nfs4_run_state_manager, clp, "%s-manager", |
791 | rpc_peeraddr2str(clp->cl_rpcclient, | 793 | rpc_peeraddr2str(clp->cl_rpcclient, |
792 | RPC_DISPLAY_ADDR)); | 794 | RPC_DISPLAY_ADDR)); |
793 | if (!IS_ERR(task)) | 795 | if (!IS_ERR(task)) |
794 | return; | 796 | return; |
795 | nfs4_clear_recover_bit(clp); | 797 | nfs4_clear_state_manager_bit(clp); |
796 | nfs_put_client(clp); | 798 | nfs_put_client(clp); |
797 | module_put(THIS_MODULE); | 799 | module_put(THIS_MODULE); |
798 | } | 800 | } |
@@ -806,8 +808,7 @@ void nfs4_schedule_state_recovery(struct nfs_client *clp) | |||
806 | return; | 808 | return; |
807 | if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) | 809 | if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) |
808 | set_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state); | 810 | set_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state); |
809 | if (test_and_set_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0) | 811 | nfs4_schedule_state_manager(clp); |
810 | nfs4_recover_state(clp); | ||
811 | } | 812 | } |
812 | 813 | ||
813 | static int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state) | 814 | static int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state) |
@@ -1106,13 +1107,10 @@ static int nfs4_reclaim_lease(struct nfs_client *clp) | |||
1106 | return status; | 1107 | return status; |
1107 | } | 1108 | } |
1108 | 1109 | ||
1109 | static int reclaimer(void *ptr) | 1110 | static void nfs4_state_manager(struct nfs_client *clp) |
1110 | { | 1111 | { |
1111 | struct nfs_client *clp = ptr; | ||
1112 | int status = 0; | 1112 | int status = 0; |
1113 | 1113 | ||
1114 | allow_signal(SIGKILL); | ||
1115 | |||
1116 | /* Ensure exclusive access to NFSv4 state */ | 1114 | /* Ensure exclusive access to NFSv4 state */ |
1117 | while (!list_empty(&clp->cl_superblocks)) { | 1115 | while (!list_empty(&clp->cl_superblocks)) { |
1118 | if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) { | 1116 | if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) { |
@@ -1161,19 +1159,28 @@ static int reclaimer(void *ptr) | |||
1161 | nfs_client_return_marked_delegations(clp); | 1159 | nfs_client_return_marked_delegations(clp); |
1162 | continue; | 1160 | continue; |
1163 | } | 1161 | } |
1162 | |||
1163 | nfs4_clear_state_manager_bit(clp); | ||
1164 | break; | 1164 | break; |
1165 | } | 1165 | } |
1166 | out: | 1166 | return; |
1167 | nfs4_clear_recover_bit(clp); | ||
1168 | nfs_put_client(clp); | ||
1169 | module_put_and_exit(0); | ||
1170 | return 0; | ||
1171 | out_error: | 1167 | out_error: |
1172 | printk(KERN_WARNING "Error: state recovery failed on NFSv4 server %s" | 1168 | printk(KERN_WARNING "Error: state manager failed on NFSv4 server %s" |
1173 | " with error %d\n", clp->cl_hostname, -status); | 1169 | " with error %d\n", clp->cl_hostname, -status); |
1174 | if (test_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) | 1170 | if (test_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) |
1175 | nfs4_state_end_reclaim_reboot(clp); | 1171 | nfs4_state_end_reclaim_reboot(clp); |
1176 | goto out; | 1172 | nfs4_clear_state_manager_bit(clp); |
1173 | } | ||
1174 | |||
1175 | static int nfs4_run_state_manager(void *ptr) | ||
1176 | { | ||
1177 | struct nfs_client *clp = ptr; | ||
1178 | |||
1179 | allow_signal(SIGKILL); | ||
1180 | nfs4_state_manager(clp); | ||
1181 | nfs_put_client(clp); | ||
1182 | module_put_and_exit(0); | ||
1183 | return 0; | ||
1177 | } | 1184 | } |
1178 | 1185 | ||
1179 | /* | 1186 | /* |