aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4state.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4state.c')
-rw-r--r--fs/nfs/nfs4state.c47
1 files changed, 29 insertions, 18 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index e5cd8cacdcee..3cc88a5d9881 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -817,6 +817,8 @@ void nfs4_schedule_state_recovery(struct nfs_client *clp)
817{ 817{
818 if (!clp) 818 if (!clp)
819 return; 819 return;
820 if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state))
821 set_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state);
820 if (test_and_set_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0) 822 if (test_and_set_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) == 0)
821 nfs4_recover_state(clp); 823 nfs4_recover_state(clp);
822} 824}
@@ -1019,6 +1021,23 @@ static void nfs4_state_end_reclaim_nograce(struct nfs_client *clp)
1019 clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state); 1021 clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state);
1020} 1022}
1021 1023
1024static void nfs4_recovery_handle_error(struct nfs_client *clp, int error)
1025{
1026 switch (error) {
1027 case -NFS4ERR_CB_PATH_DOWN:
1028 set_bit(NFS4CLNT_CB_PATH_DOWN, &clp->cl_state);
1029 break;
1030 case -NFS4ERR_STALE_CLIENTID:
1031 case -NFS4ERR_LEASE_MOVED:
1032 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1033 nfs4_state_start_reclaim_reboot(clp);
1034 break;
1035 case -NFS4ERR_EXPIRED:
1036 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1037 nfs4_state_start_reclaim_nograce(clp);
1038 }
1039}
1040
1022static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recovery_ops *ops) 1041static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recovery_ops *ops)
1023{ 1042{
1024 struct rb_node *pos; 1043 struct rb_node *pos;
@@ -1031,6 +1050,7 @@ static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recov
1031 if (status < 0) 1050 if (status < 0)
1032 break; 1051 break;
1033 } 1052 }
1053 nfs4_recovery_handle_error(clp, status);
1034 return status; 1054 return status;
1035} 1055}
1036 1056
@@ -1045,19 +1065,7 @@ static int nfs4_check_lease(struct nfs_client *clp)
1045 /* Yes there are: try to renew the old lease */ 1065 /* Yes there are: try to renew the old lease */
1046 status = nfs4_proc_renew(clp, cred); 1066 status = nfs4_proc_renew(clp, cred);
1047 put_rpccred(cred); 1067 put_rpccred(cred);
1048 switch (status) { 1068 nfs4_recovery_handle_error(clp, status);
1049 case -NFS4ERR_CB_PATH_DOWN:
1050 set_bit(NFS4CLNT_CB_PATH_DOWN, &clp->cl_state);
1051 break;
1052 case -NFS4ERR_STALE_CLIENTID:
1053 case -NFS4ERR_LEASE_MOVED:
1054 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1055 nfs4_state_start_reclaim_reboot(clp);
1056 break;
1057 case -NFS4ERR_EXPIRED:
1058 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state);
1059 nfs4_state_start_reclaim_nograce(clp);
1060 }
1061 return status; 1069 return status;
1062 } 1070 }
1063 1071
@@ -1095,8 +1103,6 @@ static int reclaimer(void *ptr)
1095 /* Ensure exclusive access to NFSv4 state */ 1103 /* Ensure exclusive access to NFSv4 state */
1096 down_write(&clp->cl_sem); 1104 down_write(&clp->cl_sem);
1097 while (!list_empty(&clp->cl_superblocks)) { 1105 while (!list_empty(&clp->cl_superblocks)) {
1098 status = nfs4_check_lease(clp);
1099
1100 if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) { 1106 if (test_and_clear_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) {
1101 /* We're going to have to re-establish a clientid */ 1107 /* We're going to have to re-establish a clientid */
1102 status = nfs4_reclaim_lease(clp); 1108 status = nfs4_reclaim_lease(clp);
@@ -1106,16 +1112,21 @@ static int reclaimer(void *ptr)
1106 continue; 1112 continue;
1107 goto out_error; 1113 goto out_error;
1108 } 1114 }
1115 clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state);
1116 }
1117
1118 if (test_and_clear_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state)) {
1119 status = nfs4_check_lease(clp);
1120 if (status != 0)
1121 continue;
1109 } 1122 }
1110 1123
1111 /* First recover reboot state... */ 1124 /* First recover reboot state... */
1112 if (test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) { 1125 if (test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) {
1113 /* Note: list is protected by exclusive lock on cl->cl_sem */ 1126 /* Note: list is protected by exclusive lock on cl->cl_sem */
1114 status = nfs4_do_reclaim(clp, &nfs4_reboot_recovery_ops); 1127 status = nfs4_do_reclaim(clp, &nfs4_reboot_recovery_ops);
1115 if (status == -NFS4ERR_STALE_CLIENTID) { 1128 if (status == -NFS4ERR_STALE_CLIENTID)
1116 set_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state);
1117 continue; 1129 continue;
1118 }
1119 nfs4_state_end_reclaim_reboot(clp); 1130 nfs4_state_end_reclaim_reboot(clp);
1120 continue; 1131 continue;
1121 } 1132 }