diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-10-19 19:47:49 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-10-23 15:27:28 -0400 |
commit | 168667c43bbafff11b46014a1e94477ff7619f45 (patch) | |
tree | 903bf11fe3b53fe0e7db6ab38d2bdc8933576879 | |
parent | 898f635c4297e91ceac675d83c4a460f26118342 (diff) |
NFSv4: The state manager must ignore EKEYEXPIRED.
Otherwise, we cannot recover state correctly.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/nfs/nfs4proc.c | 27 | ||||
-rw-r--r-- | fs/nfs/nfs4state.c | 23 |
2 files changed, 40 insertions, 10 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 88a9d93ec1bd..aa771c1af115 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -1186,7 +1186,7 @@ static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state | |||
1186 | int err; | 1186 | int err; |
1187 | do { | 1187 | do { |
1188 | err = _nfs4_do_open_reclaim(ctx, state); | 1188 | err = _nfs4_do_open_reclaim(ctx, state); |
1189 | if (err != -NFS4ERR_DELAY && err != -EKEYEXPIRED) | 1189 | if (err != -NFS4ERR_DELAY) |
1190 | break; | 1190 | break; |
1191 | nfs4_handle_exception(server, err, &exception); | 1191 | nfs4_handle_exception(server, err, &exception); |
1192 | } while (exception.retry); | 1192 | } while (exception.retry); |
@@ -1256,6 +1256,13 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state | |||
1256 | case -NFS4ERR_ADMIN_REVOKED: | 1256 | case -NFS4ERR_ADMIN_REVOKED: |
1257 | case -NFS4ERR_BAD_STATEID: | 1257 | case -NFS4ERR_BAD_STATEID: |
1258 | nfs4_state_mark_reclaim_nograce(server->nfs_client, state); | 1258 | nfs4_state_mark_reclaim_nograce(server->nfs_client, state); |
1259 | case -EKEYEXPIRED: | ||
1260 | /* | ||
1261 | * User RPCSEC_GSS context has expired. | ||
1262 | * We cannot recover this stateid now, so | ||
1263 | * skip it and allow recovery thread to | ||
1264 | * proceed. | ||
1265 | */ | ||
1259 | case -ENOMEM: | 1266 | case -ENOMEM: |
1260 | err = 0; | 1267 | err = 0; |
1261 | goto out; | 1268 | goto out; |
@@ -1603,7 +1610,6 @@ static int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state | |||
1603 | goto out; | 1610 | goto out; |
1604 | case -NFS4ERR_GRACE: | 1611 | case -NFS4ERR_GRACE: |
1605 | case -NFS4ERR_DELAY: | 1612 | case -NFS4ERR_DELAY: |
1606 | case -EKEYEXPIRED: | ||
1607 | nfs4_handle_exception(server, err, &exception); | 1613 | nfs4_handle_exception(server, err, &exception); |
1608 | err = 0; | 1614 | err = 0; |
1609 | } | 1615 | } |
@@ -3544,7 +3550,6 @@ int nfs4_proc_setclientid_confirm(struct nfs_client *clp, | |||
3544 | case -NFS4ERR_RESOURCE: | 3550 | case -NFS4ERR_RESOURCE: |
3545 | /* The IBM lawyers misread another document! */ | 3551 | /* The IBM lawyers misread another document! */ |
3546 | case -NFS4ERR_DELAY: | 3552 | case -NFS4ERR_DELAY: |
3547 | case -EKEYEXPIRED: | ||
3548 | err = nfs4_delay(clp->cl_rpcclient, &timeout); | 3553 | err = nfs4_delay(clp->cl_rpcclient, &timeout); |
3549 | } | 3554 | } |
3550 | } while (err == 0); | 3555 | } while (err == 0); |
@@ -4156,7 +4161,7 @@ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request | |||
4156 | if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) | 4161 | if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0) |
4157 | return 0; | 4162 | return 0; |
4158 | err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_RECLAIM); | 4163 | err = _nfs4_do_setlk(state, F_SETLK, request, NFS_LOCK_RECLAIM); |
4159 | if (err != -NFS4ERR_DELAY && err != -EKEYEXPIRED) | 4164 | if (err != -NFS4ERR_DELAY) |
4160 | break; | 4165 | break; |
4161 | nfs4_handle_exception(server, err, &exception); | 4166 | nfs4_handle_exception(server, err, &exception); |
4162 | } while (exception.retry); | 4167 | } while (exception.retry); |
@@ -4181,7 +4186,6 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request | |||
4181 | goto out; | 4186 | goto out; |
4182 | case -NFS4ERR_GRACE: | 4187 | case -NFS4ERR_GRACE: |
4183 | case -NFS4ERR_DELAY: | 4188 | case -NFS4ERR_DELAY: |
4184 | case -EKEYEXPIRED: | ||
4185 | nfs4_handle_exception(server, err, &exception); | 4189 | nfs4_handle_exception(server, err, &exception); |
4186 | err = 0; | 4190 | err = 0; |
4187 | } | 4191 | } |
@@ -4327,13 +4331,21 @@ int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl) | |||
4327 | nfs4_state_mark_reclaim_nograce(server->nfs_client, state); | 4331 | nfs4_state_mark_reclaim_nograce(server->nfs_client, state); |
4328 | err = 0; | 4332 | err = 0; |
4329 | goto out; | 4333 | goto out; |
4334 | case -EKEYEXPIRED: | ||
4335 | /* | ||
4336 | * User RPCSEC_GSS context has expired. | ||
4337 | * We cannot recover this stateid now, so | ||
4338 | * skip it and allow recovery thread to | ||
4339 | * proceed. | ||
4340 | */ | ||
4341 | err = 0; | ||
4342 | goto out; | ||
4330 | case -ENOMEM: | 4343 | case -ENOMEM: |
4331 | case -NFS4ERR_DENIED: | 4344 | case -NFS4ERR_DENIED: |
4332 | /* kill_proc(fl->fl_pid, SIGLOST, 1); */ | 4345 | /* kill_proc(fl->fl_pid, SIGLOST, 1); */ |
4333 | err = 0; | 4346 | err = 0; |
4334 | goto out; | 4347 | goto out; |
4335 | case -NFS4ERR_DELAY: | 4348 | case -NFS4ERR_DELAY: |
4336 | case -EKEYEXPIRED: | ||
4337 | break; | 4349 | break; |
4338 | } | 4350 | } |
4339 | err = nfs4_handle_exception(server, err, &exception); | 4351 | err = nfs4_handle_exception(server, err, &exception); |
@@ -4562,7 +4574,6 @@ static void nfs4_get_lease_time_done(struct rpc_task *task, void *calldata) | |||
4562 | switch (task->tk_status) { | 4574 | switch (task->tk_status) { |
4563 | case -NFS4ERR_DELAY: | 4575 | case -NFS4ERR_DELAY: |
4564 | case -NFS4ERR_GRACE: | 4576 | case -NFS4ERR_GRACE: |
4565 | case -EKEYEXPIRED: | ||
4566 | dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status); | 4577 | dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status); |
4567 | rpc_delay(task, NFS4_POLL_RETRY_MIN); | 4578 | rpc_delay(task, NFS4_POLL_RETRY_MIN); |
4568 | task->tk_status = 0; | 4579 | task->tk_status = 0; |
@@ -5025,7 +5036,6 @@ static int nfs41_sequence_handle_errors(struct rpc_task *task, struct nfs_client | |||
5025 | { | 5036 | { |
5026 | switch(task->tk_status) { | 5037 | switch(task->tk_status) { |
5027 | case -NFS4ERR_DELAY: | 5038 | case -NFS4ERR_DELAY: |
5028 | case -EKEYEXPIRED: | ||
5029 | rpc_delay(task, NFS4_POLL_RETRY_MAX); | 5039 | rpc_delay(task, NFS4_POLL_RETRY_MAX); |
5030 | return -EAGAIN; | 5040 | return -EAGAIN; |
5031 | default: | 5041 | default: |
@@ -5167,7 +5177,6 @@ static int nfs41_reclaim_complete_handle_errors(struct rpc_task *task, struct nf | |||
5167 | case -NFS4ERR_WRONG_CRED: /* What to do here? */ | 5177 | case -NFS4ERR_WRONG_CRED: /* What to do here? */ |
5168 | break; | 5178 | break; |
5169 | case -NFS4ERR_DELAY: | 5179 | case -NFS4ERR_DELAY: |
5170 | case -EKEYEXPIRED: | ||
5171 | rpc_delay(task, NFS4_POLL_RETRY_MAX); | 5180 | rpc_delay(task, NFS4_POLL_RETRY_MAX); |
5172 | return -EAGAIN; | 5181 | return -EAGAIN; |
5173 | default: | 5182 | default: |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 940cf7c070af..40028ac2b69c 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -1063,6 +1063,14 @@ restart: | |||
1063 | /* Mark the file as being 'closed' */ | 1063 | /* Mark the file as being 'closed' */ |
1064 | state->state = 0; | 1064 | state->state = 0; |
1065 | break; | 1065 | break; |
1066 | case -EKEYEXPIRED: | ||
1067 | /* | ||
1068 | * User RPCSEC_GSS context has expired. | ||
1069 | * We cannot recover this stateid now, so | ||
1070 | * skip it and allow recovery thread to | ||
1071 | * proceed. | ||
1072 | */ | ||
1073 | break; | ||
1066 | case -NFS4ERR_ADMIN_REVOKED: | 1074 | case -NFS4ERR_ADMIN_REVOKED: |
1067 | case -NFS4ERR_STALE_STATEID: | 1075 | case -NFS4ERR_STALE_STATEID: |
1068 | case -NFS4ERR_BAD_STATEID: | 1076 | case -NFS4ERR_BAD_STATEID: |
@@ -1181,6 +1189,14 @@ static void nfs4_state_start_reclaim_nograce(struct nfs_client *clp) | |||
1181 | nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_nograce); | 1189 | nfs4_state_mark_reclaim_helper(clp, nfs4_state_mark_reclaim_nograce); |
1182 | } | 1190 | } |
1183 | 1191 | ||
1192 | static void nfs4_warn_keyexpired(const char *s) | ||
1193 | { | ||
1194 | printk_ratelimited(KERN_WARNING "Error: state manager" | ||
1195 | " encountered RPCSEC_GSS session" | ||
1196 | " expired against NFSv4 server %s.\n", | ||
1197 | s); | ||
1198 | } | ||
1199 | |||
1184 | static int nfs4_recovery_handle_error(struct nfs_client *clp, int error) | 1200 | static int nfs4_recovery_handle_error(struct nfs_client *clp, int error) |
1185 | { | 1201 | { |
1186 | switch (error) { | 1202 | switch (error) { |
@@ -1210,6 +1226,10 @@ static int nfs4_recovery_handle_error(struct nfs_client *clp, int error) | |||
1210 | set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state); | 1226 | set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state); |
1211 | /* Zero session reset errors */ | 1227 | /* Zero session reset errors */ |
1212 | return 0; | 1228 | return 0; |
1229 | case -EKEYEXPIRED: | ||
1230 | /* Nothing we can do */ | ||
1231 | nfs4_warn_keyexpired(clp->cl_hostname); | ||
1232 | return 0; | ||
1213 | } | 1233 | } |
1214 | return error; | 1234 | return error; |
1215 | } | 1235 | } |
@@ -1420,9 +1440,10 @@ static void nfs4_set_lease_expired(struct nfs_client *clp, int status) | |||
1420 | case -NFS4ERR_DELAY: | 1440 | case -NFS4ERR_DELAY: |
1421 | case -NFS4ERR_CLID_INUSE: | 1441 | case -NFS4ERR_CLID_INUSE: |
1422 | case -EAGAIN: | 1442 | case -EAGAIN: |
1423 | case -EKEYEXPIRED: | ||
1424 | break; | 1443 | break; |
1425 | 1444 | ||
1445 | case -EKEYEXPIRED: | ||
1446 | nfs4_warn_keyexpired(clp->cl_hostname); | ||
1426 | case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery | 1447 | case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery |
1427 | * in nfs4_exchange_id */ | 1448 | * in nfs4_exchange_id */ |
1428 | default: | 1449 | default: |