aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2010-03-02 13:06:21 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2010-03-02 13:06:21 -0500
commit0f79fd6f5c52e05918e44996b0a1b18383d0fbc2 (patch)
tree480eebbdc554dfacdfd5da1897e6f704ab14bd79 /fs/nfs
parent0851de06174e9800e76b26e4be0ca94294c09c8c (diff)
NFSv4.1: Various fixes to the sequence flag error handling
Ensure that we change the EXCHANGE_ID verifier (i.e. clp->cl_boot_time) when we want to reset all state. This is mainly needed when the server tells us that it is revoking our open or lock stateids. Handle revoking of recallable state by expiring the delegations. Handle callback path issues by expiring the delegations and then resetting the session. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4state.c57
1 files changed, 45 insertions, 12 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 2931c46c4127..6c5ed51f105e 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -1255,26 +1255,59 @@ void nfs41_handle_recall_slot(struct nfs_client *clp)
1255 nfs4_schedule_state_recovery(clp); 1255 nfs4_schedule_state_recovery(clp);
1256} 1256}
1257 1257
1258static void nfs4_reset_all_state(struct nfs_client *clp)
1259{
1260 if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) {
1261 clp->cl_boot_time = CURRENT_TIME;
1262 nfs4_state_start_reclaim_nograce(clp);
1263 nfs4_schedule_state_recovery(clp);
1264 }
1265}
1266
1267static void nfs41_handle_server_reboot(struct nfs_client *clp)
1268{
1269 if (test_and_set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0) {
1270 nfs4_state_start_reclaim_reboot(clp);
1271 nfs4_schedule_state_recovery(clp);
1272 }
1273}
1274
1275static void nfs41_handle_state_revoked(struct nfs_client *clp)
1276{
1277 /* Temporary */
1278 nfs4_reset_all_state(clp);
1279}
1280
1281static void nfs41_handle_recallable_state_revoked(struct nfs_client *clp)
1282{
1283 /* This will need to handle layouts too */
1284 nfs_expire_all_delegations(clp);
1285}
1286
1287static void nfs41_handle_cb_path_down(struct nfs_client *clp)
1288{
1289 nfs_expire_all_delegations(clp);
1290 if (test_and_set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state) == 0)
1291 nfs4_schedule_state_recovery(clp);
1292}
1293
1258void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags) 1294void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags)
1259{ 1295{
1260 if (!flags) 1296 if (!flags)
1261 return; 1297 return;
1262 else if (flags & SEQ4_STATUS_RESTART_RECLAIM_NEEDED) { 1298 else if (flags & SEQ4_STATUS_RESTART_RECLAIM_NEEDED)
1263 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); 1299 nfs41_handle_server_reboot(clp);
1264 nfs4_state_start_reclaim_reboot(clp); 1300 else if (flags & (SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED |
1265 nfs4_schedule_state_recovery(clp);
1266 } else if (flags & (SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED |
1267 SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED | 1301 SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED |
1268 SEQ4_STATUS_ADMIN_STATE_REVOKED | 1302 SEQ4_STATUS_ADMIN_STATE_REVOKED |
1269 SEQ4_STATUS_RECALLABLE_STATE_REVOKED | 1303 SEQ4_STATUS_LEASE_MOVED))
1270 SEQ4_STATUS_LEASE_MOVED)) { 1304 nfs41_handle_state_revoked(clp);
1271 set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); 1305 else if (flags & SEQ4_STATUS_RECALLABLE_STATE_REVOKED)
1272 nfs4_state_start_reclaim_nograce(clp); 1306 nfs41_handle_recallable_state_revoked(clp);
1273 nfs4_schedule_state_recovery(clp); 1307 else if (flags & (SEQ4_STATUS_CB_PATH_DOWN |
1274 } else if (flags & (SEQ4_STATUS_CB_PATH_DOWN |
1275 SEQ4_STATUS_BACKCHANNEL_FAULT | 1308 SEQ4_STATUS_BACKCHANNEL_FAULT |
1276 SEQ4_STATUS_CB_PATH_DOWN_SESSION)) 1309 SEQ4_STATUS_CB_PATH_DOWN_SESSION))
1277 nfs_expire_all_delegations(clp); 1310 nfs41_handle_cb_path_down(clp);
1278} 1311}
1279 1312
1280static int nfs4_reset_session(struct nfs_client *clp) 1313static int nfs4_reset_session(struct nfs_client *clp)