summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2012-11-23 19:09:38 +0100
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-12-06 00:30:44 +0100
commit5d63360dd8daffc2bc86531e9a44ff9d4881b102 (patch)
tree6fdad98cdfbbe3830d8cc3679c435ed8c8be0606 /fs
parentNFSv4.1: If slot allocation fails due to OOM, retry more quickly (diff)
downloadlinux-5d63360dd8daffc2bc86531e9a44ff9d4881b102.tar.xz
linux-5d63360dd8daffc2bc86531e9a44ff9d4881b102.zip
NFSv4.1: Clean up session draining
Coalesce nfs4_check_drain_bc_complete and nfs4_check_drain_fc_complete into a single function that can be called when the slot table is known to be empty, then change nfs4_callback_free_slot() and nfs4_free_slot() to use it. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-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(
struct cb_layoutrecallargs *args,
void *dummy, struct cb_process_state *cps);
-extern void nfs4_check_drain_bc_complete(struct nfs4_session *ses);
-
struct cb_devicenotifyitem {
uint32_t cbd_notify_type;
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)
* A single slot, so highest used slotid is either 0 or -1
*/
tbl->highest_used_slotid = NFS4_NO_SLOT;
- nfs4_check_drain_bc_complete(session);
+ nfs4_session_drain_complete(session, tbl);
spin_unlock(&tbl->slot_tbl_lock);
}
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,
struct nfs_client **, struct rpc_cred *);
extern void nfs4_schedule_session_recovery(struct nfs4_session *, int);
extern void nfs41_server_notify_target_slotid_update(struct nfs_client *clp);
+
+extern void nfs4_session_drain_complete(struct nfs4_session *session,
+ struct nfs4_slot_table *tbl);
+
+static inline bool nfs4_session_draining(struct nfs4_session *session)
+{
+ return !!test_bit(NFS4_SESSION_DRAINING, &session->session_state);
+}
#else
static inline void nfs4_schedule_session_recovery(struct nfs4_session *session, int err)
{
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)
u32 new_max = find_last_bit(tbl->used_slots, slotid);
if (new_max < slotid)
tbl->highest_used_slotid = new_max;
- else
+ else {
tbl->highest_used_slotid = NFS4_NO_SLOT;
+ nfs4_session_drain_complete(tbl->session, tbl);
+ }
}
dprintk("%s: slotid %u highest_used_slotid %d\n", __func__,
slotid, tbl->highest_used_slotid);
@@ -458,36 +460,6 @@ bool nfs4_set_task_privileged(struct rpc_task *task, void *dummy)
return true;
}
-/*
- * Signal state manager thread if session fore channel is drained
- */
-static void nfs4_check_drain_fc_complete(struct nfs4_session *ses)
-{
- if (!test_bit(NFS4_SESSION_DRAINING, &ses->session_state)) {
- rpc_wake_up_first(&ses->fc_slot_table.slot_tbl_waitq,
- nfs4_set_task_privileged, NULL);
- return;
- }
-
- if (ses->fc_slot_table.highest_used_slotid != NFS4_NO_SLOT)
- return;
-
- dprintk("%s COMPLETE: Session Fore Channel Drained\n", __func__);
- complete(&ses->fc_slot_table.complete);
-}
-
-/*
- * Signal state manager thread if session back channel is drained
- */
-void nfs4_check_drain_bc_complete(struct nfs4_session *ses)
-{
- if (!test_bit(NFS4_SESSION_DRAINING, &ses->session_state) ||
- ses->bc_slot_table.highest_used_slotid != NFS4_NO_SLOT)
- return;
- dprintk("%s COMPLETE: Session Back Channel Drained\n", __func__);
- complete(&ses->bc_slot_table.complete);
-}
-
static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
{
struct nfs4_session *session;
@@ -504,7 +476,9 @@ static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
spin_lock(&tbl->slot_tbl_lock);
nfs4_free_slot(tbl, res->sr_slot);
- nfs4_check_drain_fc_complete(session);
+ if (!nfs4_session_draining(session))
+ rpc_wake_up_first(&tbl->slot_tbl_waitq,
+ nfs4_set_task_privileged, NULL);
spin_unlock(&tbl->slot_tbl_lock);
res->sr_slot = NULL;
}
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)
}
}
+/*
+ * Signal state manager thread if session fore channel is drained
+ */
+void nfs4_session_drain_complete(struct nfs4_session *session,
+ struct nfs4_slot_table *tbl)
+{
+ if (nfs4_session_draining(session))
+ complete(&tbl->complete);
+}
+
static int nfs4_wait_on_slot_tbl(struct nfs4_slot_table *tbl)
{
spin_lock(&tbl->slot_tbl_lock);