aboutsummaryrefslogtreecommitdiff
path: root/fs/nfs/callback_proc.c
diff options
context:
space:
mode:
authorAndy Adamson <andros@netapp.com>2010-01-20 16:06:27 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2010-02-10 08:30:59 -0500
commitb9efa1b27e25b1286504973c0a6bf0f24106faa8 (patch)
treee2cff0c8c7a33869123ea3e340d3b9ac3eefcef2 /fs/nfs/callback_proc.c
parent4911096f1a5df73c12c287a42ece4e7b5d9c19ec (diff)
nfs41: implement cb_recall_slot
Drain the fore channel and reset the max_slots to the new value. Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/callback_proc.c')
-rw-r--r--fs/nfs/callback_proc.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index 4062f7690a3..e5155d9df59 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -361,4 +361,36 @@ out:
dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
return status;
}
+
+/* Reduce the fore channel's max_slots to the target value */
+unsigned nfs4_callback_recallslot(struct cb_recallslotargs *args, void *dummy)
+{
+ struct nfs_client *clp;
+ struct nfs4_slot_table *fc_tbl;
+ int status;
+
+ status = htonl(NFS4ERR_OP_NOT_IN_SESSION);
+ clp = nfs_find_client(args->crsa_addr, 4);
+ if (clp == NULL)
+ goto out;
+
+ dprintk("NFS: CB_RECALL_SLOT request from %s target max slots %d\n",
+ rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR),
+ args->crsa_target_max_slots);
+
+ fc_tbl = &clp->cl_session->fc_slot_table;
+
+ status = htonl(NFS4ERR_BAD_HIGH_SLOT);
+ if (args->crsa_target_max_slots >= fc_tbl->max_slots ||
+ args->crsa_target_max_slots < 1)
+ goto out;
+
+ fc_tbl->target_max_slots = args->crsa_target_max_slots;
+ nfs41_handle_recall_slot(clp);
+ status = htonl(NFS4_OK);
+ nfs_put_client(clp); /* balance nfs_find_client */
+out:
+ dprintk("%s: exit with status = %d\n", __func__, ntohl(status));
+ return status;
+}
#endif /* CONFIG_NFS_V4_1 */