diff options
Diffstat (limited to 'fs/nfs/nfs4state.c')
-rw-r--r-- | fs/nfs/nfs4state.c | 60 |
1 files changed, 36 insertions, 24 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index e76427e6346f..6d263ed79e92 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -135,16 +135,30 @@ static int nfs41_setup_state_renewal(struct nfs_client *clp) | |||
135 | return status; | 135 | return status; |
136 | } | 136 | } |
137 | 137 | ||
138 | static void nfs41_end_drain_session(struct nfs_client *clp, | 138 | static void nfs4_end_drain_session(struct nfs_client *clp) |
139 | struct nfs4_session *ses) | ||
140 | { | 139 | { |
141 | if (test_and_clear_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state)) | 140 | struct nfs4_session *ses = clp->cl_session; |
142 | rpc_wake_up(&ses->fc_slot_table.slot_tbl_waitq); | 141 | int max_slots; |
142 | |||
143 | if (test_and_clear_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state)) { | ||
144 | spin_lock(&ses->fc_slot_table.slot_tbl_lock); | ||
145 | max_slots = ses->fc_slot_table.max_slots; | ||
146 | while (max_slots--) { | ||
147 | struct rpc_task *task; | ||
148 | |||
149 | task = rpc_wake_up_next(&ses->fc_slot_table. | ||
150 | slot_tbl_waitq); | ||
151 | if (!task) | ||
152 | break; | ||
153 | rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED); | ||
154 | } | ||
155 | spin_unlock(&ses->fc_slot_table.slot_tbl_lock); | ||
156 | } | ||
143 | } | 157 | } |
144 | 158 | ||
145 | static int nfs41_begin_drain_session(struct nfs_client *clp, | 159 | static int nfs4_begin_drain_session(struct nfs_client *clp) |
146 | struct nfs4_session *ses) | ||
147 | { | 160 | { |
161 | struct nfs4_session *ses = clp->cl_session; | ||
148 | struct nfs4_slot_table *tbl = &ses->fc_slot_table; | 162 | struct nfs4_slot_table *tbl = &ses->fc_slot_table; |
149 | 163 | ||
150 | spin_lock(&tbl->slot_tbl_lock); | 164 | spin_lock(&tbl->slot_tbl_lock); |
@@ -162,16 +176,13 @@ int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred) | |||
162 | { | 176 | { |
163 | int status; | 177 | int status; |
164 | 178 | ||
165 | status = nfs41_begin_drain_session(clp, clp->cl_session); | 179 | nfs4_begin_drain_session(clp); |
166 | if (status != 0) | ||
167 | goto out; | ||
168 | status = nfs4_proc_exchange_id(clp, cred); | 180 | status = nfs4_proc_exchange_id(clp, cred); |
169 | if (status != 0) | 181 | if (status != 0) |
170 | goto out; | 182 | goto out; |
171 | status = nfs4_proc_create_session(clp); | 183 | status = nfs4_proc_create_session(clp); |
172 | if (status != 0) | 184 | if (status != 0) |
173 | goto out; | 185 | goto out; |
174 | nfs41_end_drain_session(clp, clp->cl_session); | ||
175 | nfs41_setup_state_renewal(clp); | 186 | nfs41_setup_state_renewal(clp); |
176 | nfs_mark_client_ready(clp, NFS_CS_READY); | 187 | nfs_mark_client_ready(clp, NFS_CS_READY); |
177 | out: | 188 | out: |
@@ -755,16 +766,21 @@ struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter) | |||
755 | return new; | 766 | return new; |
756 | } | 767 | } |
757 | 768 | ||
758 | void nfs_free_seqid(struct nfs_seqid *seqid) | 769 | void nfs_release_seqid(struct nfs_seqid *seqid) |
759 | { | 770 | { |
760 | if (!list_empty(&seqid->list)) { | 771 | if (!list_empty(&seqid->list)) { |
761 | struct rpc_sequence *sequence = seqid->sequence->sequence; | 772 | struct rpc_sequence *sequence = seqid->sequence->sequence; |
762 | 773 | ||
763 | spin_lock(&sequence->lock); | 774 | spin_lock(&sequence->lock); |
764 | list_del(&seqid->list); | 775 | list_del_init(&seqid->list); |
765 | spin_unlock(&sequence->lock); | 776 | spin_unlock(&sequence->lock); |
766 | rpc_wake_up(&sequence->wait); | 777 | rpc_wake_up(&sequence->wait); |
767 | } | 778 | } |
779 | } | ||
780 | |||
781 | void nfs_free_seqid(struct nfs_seqid *seqid) | ||
782 | { | ||
783 | nfs_release_seqid(seqid); | ||
768 | kfree(seqid); | 784 | kfree(seqid); |
769 | } | 785 | } |
770 | 786 | ||
@@ -1257,13 +1273,9 @@ void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags) | |||
1257 | 1273 | ||
1258 | static int nfs4_reset_session(struct nfs_client *clp) | 1274 | static int nfs4_reset_session(struct nfs_client *clp) |
1259 | { | 1275 | { |
1260 | struct nfs4_session *ses = clp->cl_session; | ||
1261 | int status; | 1276 | int status; |
1262 | 1277 | ||
1263 | status = nfs41_begin_drain_session(clp, ses); | 1278 | nfs4_begin_drain_session(clp); |
1264 | if (status != 0) | ||
1265 | return status; | ||
1266 | |||
1267 | status = nfs4_proc_destroy_session(clp->cl_session); | 1279 | status = nfs4_proc_destroy_session(clp->cl_session); |
1268 | if (status && status != -NFS4ERR_BADSESSION && | 1280 | if (status && status != -NFS4ERR_BADSESSION && |
1269 | status != -NFS4ERR_DEADSESSION) { | 1281 | status != -NFS4ERR_DEADSESSION) { |
@@ -1279,19 +1291,17 @@ static int nfs4_reset_session(struct nfs_client *clp) | |||
1279 | out: | 1291 | out: |
1280 | /* | 1292 | /* |
1281 | * Let the state manager reestablish state | 1293 | * Let the state manager reestablish state |
1282 | * without waking other tasks yet. | ||
1283 | */ | 1294 | */ |
1284 | if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state)) { | 1295 | if (!test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) && |
1285 | /* Wake up the next rpc task */ | 1296 | status == 0) |
1286 | nfs41_end_drain_session(clp, ses); | 1297 | nfs41_setup_state_renewal(clp); |
1287 | if (status == 0) | 1298 | |
1288 | nfs41_setup_state_renewal(clp); | ||
1289 | } | ||
1290 | return status; | 1299 | return status; |
1291 | } | 1300 | } |
1292 | 1301 | ||
1293 | #else /* CONFIG_NFS_V4_1 */ | 1302 | #else /* CONFIG_NFS_V4_1 */ |
1294 | static int nfs4_reset_session(struct nfs_client *clp) { return 0; } | 1303 | static int nfs4_reset_session(struct nfs_client *clp) { return 0; } |
1304 | static int nfs4_end_drain_session(struct nfs_client *clp) { return 0; } | ||
1295 | #endif /* CONFIG_NFS_V4_1 */ | 1305 | #endif /* CONFIG_NFS_V4_1 */ |
1296 | 1306 | ||
1297 | /* Set NFS4CLNT_LEASE_EXPIRED for all v4.0 errors and for recoverable errors | 1307 | /* Set NFS4CLNT_LEASE_EXPIRED for all v4.0 errors and for recoverable errors |
@@ -1382,6 +1392,7 @@ static void nfs4_state_manager(struct nfs_client *clp) | |||
1382 | goto out_error; | 1392 | goto out_error; |
1383 | } | 1393 | } |
1384 | 1394 | ||
1395 | nfs4_end_drain_session(clp); | ||
1385 | if (test_and_clear_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) { | 1396 | if (test_and_clear_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) { |
1386 | nfs_client_return_marked_delegations(clp); | 1397 | nfs_client_return_marked_delegations(clp); |
1387 | continue; | 1398 | continue; |
@@ -1398,6 +1409,7 @@ static void nfs4_state_manager(struct nfs_client *clp) | |||
1398 | out_error: | 1409 | out_error: |
1399 | printk(KERN_WARNING "Error: state manager failed on NFSv4 server %s" | 1410 | printk(KERN_WARNING "Error: state manager failed on NFSv4 server %s" |
1400 | " with error %d\n", clp->cl_hostname, -status); | 1411 | " with error %d\n", clp->cl_hostname, -status); |
1412 | nfs4_end_drain_session(clp); | ||
1401 | nfs4_clear_state_manager_bit(clp); | 1413 | nfs4_clear_state_manager_bit(clp); |
1402 | } | 1414 | } |
1403 | 1415 | ||