aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/delegation.c2
-rw-r--r--fs/nfs/nfs4_fs.h2
-rw-r--r--fs/nfs/nfs4proc.c4
-rw-r--r--fs/nfs/nfs4state.c49
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
40enum nfs4_client_state { 40enum 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
770static int reclaimer(void *); 770static int nfs4_run_state_manager(void *);
771 771
772static inline void nfs4_clear_recover_bit(struct nfs_client *clp) 772static 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 */
784static void nfs4_recover_state(struct nfs_client *clp) 784static 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
813static int nfs4_state_mark_reclaim_reboot(struct nfs_client *clp, struct nfs4_state *state) 814static 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
1109static int reclaimer(void *ptr) 1110static 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 }
1166out: 1166 return;
1167 nfs4_clear_recover_bit(clp);
1168 nfs_put_client(clp);
1169 module_put_and_exit(0);
1170 return 0;
1171out_error: 1167out_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
1175static 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/*