aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/callback.h2
-rw-r--r--fs/nfs/callback_xdr.c2
-rw-r--r--fs/nfs/nfs4_fs.h8
-rw-r--r--fs/nfs/nfs4proc.c38
-rw-r--r--fs/nfs/nfs4state.c10
5 files changed, 25 insertions, 35 deletions
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h
index e75631e264f4..efd54f0a4c46 100644
--- a/fs/nfs/callback.h
+++ b/fs/nfs/callback.h
@@ -167,8 +167,6 @@ extern __be32 nfs4_callback_layoutrecall(
167 struct cb_layoutrecallargs *args, 167 struct cb_layoutrecallargs *args,
168 void *dummy, struct cb_process_state *cps); 168 void *dummy, struct cb_process_state *cps);
169 169
170extern void nfs4_check_drain_bc_complete(struct nfs4_session *ses);
171
172struct cb_devicenotifyitem { 170struct cb_devicenotifyitem {
173 uint32_t cbd_notify_type; 171 uint32_t cbd_notify_type;
174 uint32_t cbd_layout_type; 172 uint32_t cbd_layout_type;
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index 81e8c7d4c2e8..ea6a7b190e6b 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -762,7 +762,7 @@ static void nfs4_callback_free_slot(struct nfs4_session *session)
762 * A single slot, so highest used slotid is either 0 or -1 762 * A single slot, so highest used slotid is either 0 or -1
763 */ 763 */
764 tbl->highest_used_slotid = NFS4_NO_SLOT; 764 tbl->highest_used_slotid = NFS4_NO_SLOT;
765 nfs4_check_drain_bc_complete(session); 765 nfs4_session_drain_complete(session, tbl);
766 spin_unlock(&tbl->slot_tbl_lock); 766 spin_unlock(&tbl->slot_tbl_lock);
767} 767}
768 768
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 0a109ec75e69..16b19372c4ba 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -335,6 +335,14 @@ int nfs41_discover_server_trunking(struct nfs_client *clp,
335 struct nfs_client **, struct rpc_cred *); 335 struct nfs_client **, struct rpc_cred *);
336extern void nfs4_schedule_session_recovery(struct nfs4_session *, int); 336extern void nfs4_schedule_session_recovery(struct nfs4_session *, int);
337extern void nfs41_server_notify_target_slotid_update(struct nfs_client *clp); 337extern void nfs41_server_notify_target_slotid_update(struct nfs_client *clp);
338
339extern void nfs4_session_drain_complete(struct nfs4_session *session,
340 struct nfs4_slot_table *tbl);
341
342static inline bool nfs4_session_draining(struct nfs4_session *session)
343{
344 return !!test_bit(NFS4_SESSION_DRAINING, &session->session_state);
345}
338#else 346#else
339static inline void nfs4_schedule_session_recovery(struct nfs4_session *session, int err) 347static inline void nfs4_schedule_session_recovery(struct nfs4_session *session, int err)
340{ 348{
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index e9e4d6393f1b..0b0f11be40f9 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -445,8 +445,10 @@ nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot)
445 u32 new_max = find_last_bit(tbl->used_slots, slotid); 445 u32 new_max = find_last_bit(tbl->used_slots, slotid);
446 if (new_max < slotid) 446 if (new_max < slotid)
447 tbl->highest_used_slotid = new_max; 447 tbl->highest_used_slotid = new_max;
448 else 448 else {
449 tbl->highest_used_slotid = NFS4_NO_SLOT; 449 tbl->highest_used_slotid = NFS4_NO_SLOT;
450 nfs4_session_drain_complete(tbl->session, tbl);
451 }
450 } 452 }
451 dprintk("%s: slotid %u highest_used_slotid %d\n", __func__, 453 dprintk("%s: slotid %u highest_used_slotid %d\n", __func__,
452 slotid, tbl->highest_used_slotid); 454 slotid, tbl->highest_used_slotid);
@@ -458,36 +460,6 @@ bool nfs4_set_task_privileged(struct rpc_task *task, void *dummy)
458 return true; 460 return true;
459} 461}
460 462
461/*
462 * Signal state manager thread if session fore channel is drained
463 */
464static void nfs4_check_drain_fc_complete(struct nfs4_session *ses)
465{
466 if (!test_bit(NFS4_SESSION_DRAINING, &ses->session_state)) {
467 rpc_wake_up_first(&ses->fc_slot_table.slot_tbl_waitq,
468 nfs4_set_task_privileged, NULL);
469 return;
470 }
471
472 if (ses->fc_slot_table.highest_used_slotid != NFS4_NO_SLOT)
473 return;
474
475 dprintk("%s COMPLETE: Session Fore Channel Drained\n", __func__);
476 complete(&ses->fc_slot_table.complete);
477}
478
479/*
480 * Signal state manager thread if session back channel is drained
481 */
482void nfs4_check_drain_bc_complete(struct nfs4_session *ses)
483{
484 if (!test_bit(NFS4_SESSION_DRAINING, &ses->session_state) ||
485 ses->bc_slot_table.highest_used_slotid != NFS4_NO_SLOT)
486 return;
487 dprintk("%s COMPLETE: Session Back Channel Drained\n", __func__);
488 complete(&ses->bc_slot_table.complete);
489}
490
491static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res) 463static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
492{ 464{
493 struct nfs4_session *session; 465 struct nfs4_session *session;
@@ -504,7 +476,9 @@ static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
504 476
505 spin_lock(&tbl->slot_tbl_lock); 477 spin_lock(&tbl->slot_tbl_lock);
506 nfs4_free_slot(tbl, res->sr_slot); 478 nfs4_free_slot(tbl, res->sr_slot);
507 nfs4_check_drain_fc_complete(session); 479 if (!nfs4_session_draining(session))
480 rpc_wake_up_first(&tbl->slot_tbl_waitq,
481 nfs4_set_task_privileged, NULL);
508 spin_unlock(&tbl->slot_tbl_lock); 482 spin_unlock(&tbl->slot_tbl_lock);
509 res->sr_slot = NULL; 483 res->sr_slot = NULL;
510} 484}
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 896be2126f7e..1fb3e6c6f993 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -271,6 +271,16 @@ static void nfs4_end_drain_session(struct nfs_client *clp)
271 } 271 }
272} 272}
273 273
274/*
275 * Signal state manager thread if session fore channel is drained
276 */
277void nfs4_session_drain_complete(struct nfs4_session *session,
278 struct nfs4_slot_table *tbl)
279{
280 if (nfs4_session_draining(session))
281 complete(&tbl->complete);
282}
283
274static int nfs4_wait_on_slot_tbl(struct nfs4_slot_table *tbl) 284static int nfs4_wait_on_slot_tbl(struct nfs4_slot_table *tbl)
275{ 285{
276 spin_lock(&tbl->slot_tbl_lock); 286 spin_lock(&tbl->slot_tbl_lock);