diff options
Diffstat (limited to 'fs/nfs/nfs4state.c')
-rw-r--r-- | fs/nfs/nfs4state.c | 47 |
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 | ||
1024 | static 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 | |||
1022 | static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recovery_ops *ops) | 1041 | static 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 | } |