diff options
author | Andy Adamson <andros@netapp.com> | 2009-04-01 09:22:39 -0400 |
---|---|---|
committer | Benny Halevy <bhalevy@panasas.com> | 2009-06-17 15:25:06 -0400 |
commit | c3fad1b1aaf850bf692642642ace7cd0d64af0a3 (patch) | |
tree | ff8822016d004d9f0cbd67a3373f5f1f4527f363 /fs/nfs/nfs4state.c | |
parent | 76db6d9500caeaa774a3e32a997eba30bbdc176b (diff) |
nfs41: add session reset to state manager
Move the code to reset a session from the session_reclaimer to the
nfs4_state_manager. Destroy the session, and create a new one. Treat
NFS4ERR_BADSESSION and NFS4ERR_DEADSESSION as a successful
nfs4_proc_destroy_session. Signal nfs4_proc_create_session that this is a
session reset so that the session slot table is re-used.
If the clientid is stale, set both NFS4CLNT_LEASE_EXPIRED and
NFS4CLNT_SESSION_SETUP bits and retry.
Use a switch statement in nfs4_session_recovery_handle_error for future
patche which will add handling for other errors.
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: session reset in nfs4_recovery_handle_error]
Signed-off-by: Andy Adamson <andros@netapp.com>
[nfs41: reset session on nfs4_do_reclaim session reset error]
If nfs4_do_reclaim gets a session reset error, nfs4_recovery_handle_error
will set the NFS4CLNT_SESSION_SETUP bit, and the state manager should
continue processing to reset the session.
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[move nfs4_proc_destroy_session declaration here]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4state.c')
-rw-r--r-- | fs/nfs/nfs4state.c | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index df5b4807daa7..8b7f007adc42 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -1042,6 +1042,14 @@ static void nfs4_recovery_handle_error(struct nfs_client *clp, int error) | |||
1042 | case -NFS4ERR_EXPIRED: | 1042 | case -NFS4ERR_EXPIRED: |
1043 | set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); | 1043 | set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); |
1044 | nfs4_state_start_reclaim_nograce(clp); | 1044 | nfs4_state_start_reclaim_nograce(clp); |
1045 | case -NFS4ERR_BADSESSION: | ||
1046 | case -NFS4ERR_BADSLOT: | ||
1047 | case -NFS4ERR_BAD_HIGH_SLOT: | ||
1048 | case -NFS4ERR_DEADSESSION: | ||
1049 | case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: | ||
1050 | case -NFS4ERR_SEQ_FALSE_RETRY: | ||
1051 | case -NFS4ERR_SEQ_MISORDERED: | ||
1052 | set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state); | ||
1045 | } | 1053 | } |
1046 | } | 1054 | } |
1047 | 1055 | ||
@@ -1114,6 +1122,36 @@ static int nfs4_reclaim_lease(struct nfs_client *clp) | |||
1114 | } | 1122 | } |
1115 | 1123 | ||
1116 | #ifdef CONFIG_NFS_V4_1 | 1124 | #ifdef CONFIG_NFS_V4_1 |
1125 | static void nfs4_session_recovery_handle_error(struct nfs_client *clp, int err) | ||
1126 | { | ||
1127 | switch (err) { | ||
1128 | case -NFS4ERR_STALE_CLIENTID: | ||
1129 | set_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state); | ||
1130 | set_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state); | ||
1131 | } | ||
1132 | } | ||
1133 | |||
1134 | static int nfs4_reset_session(struct nfs_client *clp) | ||
1135 | { | ||
1136 | int status; | ||
1137 | |||
1138 | status = nfs4_proc_destroy_session(clp->cl_session); | ||
1139 | if (status && status != -NFS4ERR_BADSESSION && | ||
1140 | status != -NFS4ERR_DEADSESSION) { | ||
1141 | nfs4_session_recovery_handle_error(clp, status); | ||
1142 | goto out; | ||
1143 | } | ||
1144 | |||
1145 | memset(clp->cl_session->sess_id.data, 0, NFS4_MAX_SESSIONID_LEN); | ||
1146 | status = nfs4_proc_create_session(clp, 1); | ||
1147 | if (status) | ||
1148 | nfs4_session_recovery_handle_error(clp, status); | ||
1149 | /* fall through*/ | ||
1150 | out: | ||
1151 | /* Wake up the next rpc task even on error */ | ||
1152 | rpc_wake_up_next(&clp->cl_session->fc_slot_table.slot_tbl_waitq); | ||
1153 | return status; | ||
1154 | } | ||
1117 | 1155 | ||
1118 | static int nfs4_initialize_session(struct nfs_client *clp) | 1156 | static int nfs4_initialize_session(struct nfs_client *clp) |
1119 | { | 1157 | { |
@@ -1131,6 +1169,7 @@ static int nfs4_initialize_session(struct nfs_client *clp) | |||
1131 | return status; | 1169 | return status; |
1132 | } | 1170 | } |
1133 | #else /* CONFIG_NFS_V4_1 */ | 1171 | #else /* CONFIG_NFS_V4_1 */ |
1172 | static int nfs4_reset_session(struct nfs_client *clp) { return 0; } | ||
1134 | static int nfs4_initialize_session(struct nfs_client *clp) { return 0; } | 1173 | static int nfs4_initialize_session(struct nfs_client *clp) { return 0; } |
1135 | #endif /* CONFIG_NFS_V4_1 */ | 1174 | #endif /* CONFIG_NFS_V4_1 */ |
1136 | 1175 | ||
@@ -1160,10 +1199,13 @@ static void nfs4_state_manager(struct nfs_client *clp) | |||
1160 | if (status != 0) | 1199 | if (status != 0) |
1161 | continue; | 1200 | continue; |
1162 | } | 1201 | } |
1163 | /* Setup the session */ | 1202 | /* Initialize or reset the session */ |
1164 | if (nfs4_has_session(clp) && | 1203 | if (nfs4_has_session(clp) && |
1165 | test_and_clear_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)) { | 1204 | test_and_clear_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)) { |
1166 | status = nfs4_initialize_session(clp); | 1205 | if (clp->cl_cons_state == NFS_CS_SESSION_INITING) |
1206 | status = nfs4_initialize_session(clp); | ||
1207 | else | ||
1208 | status = nfs4_reset_session(clp); | ||
1167 | if (status) { | 1209 | if (status) { |
1168 | if (status == -NFS4ERR_STALE_CLIENTID) | 1210 | if (status == -NFS4ERR_STALE_CLIENTID) |
1169 | continue; | 1211 | continue; |
@@ -1175,6 +1217,8 @@ static void nfs4_state_manager(struct nfs_client *clp) | |||
1175 | status = nfs4_do_reclaim(clp, &nfs4_reboot_recovery_ops); | 1217 | status = nfs4_do_reclaim(clp, &nfs4_reboot_recovery_ops); |
1176 | if (status == -NFS4ERR_STALE_CLIENTID) | 1218 | if (status == -NFS4ERR_STALE_CLIENTID) |
1177 | continue; | 1219 | continue; |
1220 | if (test_bit(NFS4CLNT_SESSION_SETUP, &clp->cl_state)) | ||
1221 | continue; | ||
1178 | nfs4_state_end_reclaim_reboot(clp); | 1222 | nfs4_state_end_reclaim_reboot(clp); |
1179 | continue; | 1223 | continue; |
1180 | } | 1224 | } |
@@ -1188,6 +1232,9 @@ static void nfs4_state_manager(struct nfs_client *clp) | |||
1188 | continue; | 1232 | continue; |
1189 | if (status == -NFS4ERR_EXPIRED) | 1233 | if (status == -NFS4ERR_EXPIRED) |
1190 | continue; | 1234 | continue; |
1235 | if (test_bit(NFS4CLNT_SESSION_SETUP, | ||
1236 | &clp->cl_state)) | ||
1237 | continue; | ||
1191 | goto out_error; | 1238 | goto out_error; |
1192 | } else | 1239 | } else |
1193 | nfs4_state_end_reclaim_nograce(clp); | 1240 | nfs4_state_end_reclaim_nograce(clp); |