diff options
Diffstat (limited to 'fs/nfs/nfs4state.c')
-rw-r--r-- | fs/nfs/nfs4state.c | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 96524c5dca6b..aa0b02a610c4 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/kthread.h> | 46 | #include <linux/kthread.h> |
47 | #include <linux/module.h> | 47 | #include <linux/module.h> |
48 | #include <linux/random.h> | 48 | #include <linux/random.h> |
49 | #include <linux/ratelimit.h> | ||
49 | #include <linux/workqueue.h> | 50 | #include <linux/workqueue.h> |
50 | #include <linux/bitops.h> | 51 | #include <linux/bitops.h> |
51 | 52 | ||
@@ -1063,6 +1064,14 @@ restart: | |||
1063 | /* Mark the file as being 'closed' */ | 1064 | /* Mark the file as being 'closed' */ |
1064 | state->state = 0; | 1065 | state->state = 0; |
1065 | break; | 1066 | break; |
1067 | case -EKEYEXPIRED: | ||
1068 | /* | ||
1069 | * User RPCSEC_GSS context has expired. | ||
1070 | * We cannot recover this stateid now, so | ||
1071 | * skip it and allow recovery thread to | ||
1072 | * proceed. | ||
1073 | */ | ||
1074 | break; | ||
1066 | case -NFS4ERR_ADMIN_REVOKED: | 1075 | case -NFS4ERR_ADMIN_REVOKED: |
1067 | case -NFS4ERR_STALE_STATEID: | 1076 | case -NFS4ERR_STALE_STATEID: |
1068 | case -NFS4ERR_BAD_STATEID: | 1077 | case -NFS4ERR_BAD_STATEID: |
@@ -1138,16 +1147,14 @@ static void nfs4_reclaim_complete(struct nfs_client *clp, | |||
1138 | (void)ops->reclaim_complete(clp); | 1147 | (void)ops->reclaim_complete(clp); |
1139 | } | 1148 | } |
1140 | 1149 | ||
1141 | static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp) | 1150 | static int nfs4_state_clear_reclaim_reboot(struct nfs_client *clp) |
1142 | { | 1151 | { |
1143 | struct nfs4_state_owner *sp; | 1152 | struct nfs4_state_owner *sp; |
1144 | struct rb_node *pos; | 1153 | struct rb_node *pos; |
1145 | struct nfs4_state *state; | 1154 | struct nfs4_state *state; |
1146 | 1155 | ||
1147 | if (!test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) | 1156 | if (!test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) |
1148 | return; | 1157 | return 0; |
1149 | |||
1150 | nfs4_reclaim_complete(clp, clp->cl_mvops->reboot_recovery_ops); | ||
1151 | 1158 | ||
1152 | for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) { | 1159 | for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) { |
1153 | sp = rb_entry(pos, struct nfs4_state_owner, so_client_node); | 1160 | sp = rb_entry(pos, struct nfs4_state_owner, so_client_node); |
@@ -1161,6 +1168,14 @@ static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp) | |||
1161 | } | 1168 | } |
1162 | 1169 | ||
1163 | nfs_delegation_reap_unclaimed(clp); | 1170 | nfs_delegation_reap_unclaimed(clp); |
1171 | return 1; | ||
1172 | } | ||
1173 | |||
1174 | static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp) | ||
1175 | { | ||
1176 | if (!nfs4_state_clear_reclaim_reboot(clp)) | ||
1177 | return; | ||
1178 | nfs4_reclaim_complete(clp, clp->cl_mvops->reboot_recovery_ops); | ||
1164 | } | 1179 | } |
1165 | 1180 | ||
1166 | static void nfs_delegation_clear_all(struct nfs_client *clp) | 1181 | static void nfs_delegation_clear_all(struct nfs_client *clp) |
@@ -1175,6 +1190,14 @@ static void nfs4_state_start_reclaim_nograce(struct nfs_client *clp) | |||
1175 | nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_nograce); | 1190 | nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_nograce); |
1176 | } | 1191 | } |
1177 | 1192 | ||
1193 | static void nfs4_warn_keyexpired(const char *s) | ||
1194 | { | ||
1195 | printk_ratelimited(KERN_WARNING "Error: state manager" | ||
1196 | " encountered RPCSEC_GSS session" | ||
1197 | " expired against NFSv4 server %s.\n", | ||
1198 | s); | ||
1199 | } | ||
1200 | |||
1178 | static int nfs4_recovery_handle_error(struct nfs_client *clp, int error) | 1201 | static int nfs4_recovery_handle_error(struct nfs_client *clp, int error) |
1179 | { | 1202 | { |
1180 | switch (error) { | 1203 | switch (error) { |
@@ -1187,7 +1210,7 @@ static int nfs4_recovery_handle_error(struct nfs_client *clp, int error) | |||
1187 | case -NFS4ERR_STALE_CLIENTID: | 1210 | case -NFS4ERR_STALE_CLIENTID: |
1188 | case -NFS4ERR_LEASE_MOVED: | 1211 | case -NFS4ERR_LEASE_MOVED: |
1189 | set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); | 1212 | set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); |
1190 | nfs4_state_end_reclaim_reboot(clp); | 1213 | nfs4_state_clear_reclaim_reboot(clp); |
1191 | nfs4_state_start_reclaim_reboot(clp); | 1214 | nfs4_state_start_reclaim_reboot(clp); |
1192 | break; | 1215 | break; |
1193 | case -NFS4ERR_EXPIRED: | 1216 | case -NFS4ERR_EXPIRED: |
@@ -1204,6 +1227,10 @@ static int nfs4_recovery_handle_error(struct nfs_client *clp, int error) | |||
1204 | set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state); | 1227 | set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state); |
1205 | /* Zero session reset errors */ | 1228 | /* Zero session reset errors */ |
1206 | return 0; | 1229 | return 0; |
1230 | case -EKEYEXPIRED: | ||
1231 | /* Nothing we can do */ | ||
1232 | nfs4_warn_keyexpired(clp->cl_hostname); | ||
1233 | return 0; | ||
1207 | } | 1234 | } |
1208 | return error; | 1235 | return error; |
1209 | } | 1236 | } |
@@ -1414,9 +1441,10 @@ static void nfs4_set_lease_expired(struct nfs_client *clp, int status) | |||
1414 | case -NFS4ERR_DELAY: | 1441 | case -NFS4ERR_DELAY: |
1415 | case -NFS4ERR_CLID_INUSE: | 1442 | case -NFS4ERR_CLID_INUSE: |
1416 | case -EAGAIN: | 1443 | case -EAGAIN: |
1417 | case -EKEYEXPIRED: | ||
1418 | break; | 1444 | break; |
1419 | 1445 | ||
1446 | case -EKEYEXPIRED: | ||
1447 | nfs4_warn_keyexpired(clp->cl_hostname); | ||
1420 | case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery | 1448 | case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery |
1421 | * in nfs4_exchange_id */ | 1449 | * in nfs4_exchange_id */ |
1422 | default: | 1450 | default: |