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.c40
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
1141static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp) 1150static 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
1174static 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
1166static void nfs_delegation_clear_all(struct nfs_client *clp) 1181static 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
1193static 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
1178static int nfs4_recovery_handle_error(struct nfs_client *clp, int error) 1201static 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: