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>
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index a0c35ab..ecd4ed3 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -389,6 +389,7 @@
 {
 	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 @@
 	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)