summaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2012-11-26 16:16:54 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-12-06 00:30:47 +0100
commitc10e449827e6008ef5a4a71c0247c7eb73948e1b (patch)
tree7512d993fc182b24655d91ea930706451c0591e6 /fs/nfs/nfs4proc.c
parent0ca3f4825ac92a10aa8f6534f765c44f22778dd3 (diff)
NFSv4.1: Ping server when our session table limits are too high
If the server requests a lower target_highest_slotid, then ensure that we ping it with at least one RPC call containing an appropriate SEQUENCE op. This ensures that the server won't need to send a recall callback in order to shrink the slot table. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index a0c35ab12a6..ecd4ed3a4f6 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -389,6 +389,7 @@ static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
{
struct nfs4_session *session;
struct nfs4_slot_table *tbl;
+ bool send_new_highest_used_slotid = false;
if (!res->sr_slot) {
/* just wake up the next guy waiting since
@@ -400,12 +401,25 @@ static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
session = tbl->session;
spin_lock(&tbl->slot_tbl_lock);
+ /* Be nice to the server: try to ensure that the last transmitted
+ * value for highest_user_slotid <= target_highest_slotid
+ */
+ if (tbl->highest_used_slotid > tbl->target_highest_slotid)
+ send_new_highest_used_slotid = true;
+
nfs4_free_slot(tbl, res->sr_slot);
- if (!nfs4_session_draining(session))
- rpc_wake_up_first(&tbl->slot_tbl_waitq,
- nfs4_set_task_privileged, NULL);
+
+ if (tbl->highest_used_slotid != NFS4_NO_SLOT)
+ send_new_highest_used_slotid = false;
+ if (!nfs4_session_draining(session)) {
+ if (rpc_wake_up_first(&tbl->slot_tbl_waitq,
+ nfs4_set_task_privileged, NULL) != NULL)
+ send_new_highest_used_slotid = false;
+ }
spin_unlock(&tbl->slot_tbl_lock);
res->sr_slot = NULL;
+ if (send_new_highest_used_slotid)
+ nfs41_server_notify_highest_slotid_update(session->clp);
}
static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res)