aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/callback_xdr.c
diff options
context:
space:
mode:
authorAndy Adamson <andros@netapp.com>2011-01-05 21:04:34 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-01-06 14:46:25 -0500
commit42acd021824578fa0eeb6eb58d457c23ec5dc9c0 (patch)
tree7affe8e1108373906eefcea00498df088b6dfccb /fs/nfs/callback_xdr.c
parentece0de633c4d9106c39ea9f0db1638c42ead2541 (diff)
NFS add session back channel draining
Currently session draining only drains the fore channel. The back channel processing must also be drained. Use the back channel highest_slot_used to indicate that a callback is being processed by the callback thread. Move the session complete to be per channel. When the session is draininig, wait for any current back channel processing to complete and stop all new back channel processing by returning NFS4ERR_DELAY to the back channel client. Drain the back channel, then the fore channel. Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/callback_xdr.c')
-rw-r--r--fs/nfs/callback_xdr.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index dbd0d649805c..7a2d6c5864ca 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -596,6 +596,37 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op)
596 return htonl(NFS_OK); 596 return htonl(NFS_OK);
597} 597}
598 598
599static void nfs4_callback_free_slot(struct nfs4_session *session)
600{
601 struct nfs4_slot_table *tbl = &session->bc_slot_table;
602
603 spin_lock(&tbl->slot_tbl_lock);
604 /*
605 * Let the state manager know callback processing done.
606 * A single slot, so highest used slotid is either 0 or -1
607 */
608 tbl->highest_used_slotid--;
609 nfs4_check_drain_bc_complete(session);
610 spin_unlock(&tbl->slot_tbl_lock);
611}
612
613static void nfs4_cb_free_slot(struct nfs_client *clp)
614{
615 if (clp && clp->cl_session)
616 nfs4_callback_free_slot(clp->cl_session);
617}
618
619/* A single slot, so highest used slotid is either 0 or -1 */
620void nfs4_cb_take_slot(struct nfs_client *clp)
621{
622 struct nfs4_slot_table *tbl = &clp->cl_session->bc_slot_table;
623
624 spin_lock(&tbl->slot_tbl_lock);
625 tbl->highest_used_slotid++;
626 BUG_ON(tbl->highest_used_slotid != 0);
627 spin_unlock(&tbl->slot_tbl_lock);
628}
629
599#else /* CONFIG_NFS_V4_1 */ 630#else /* CONFIG_NFS_V4_1 */
600 631
601static __be32 632static __be32
@@ -604,6 +635,9 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op)
604 return htonl(NFS4ERR_MINOR_VERS_MISMATCH); 635 return htonl(NFS4ERR_MINOR_VERS_MISMATCH);
605} 636}
606 637
638static void nfs4_cb_free_slot(struct nfs_client *clp)
639{
640}
607#endif /* CONFIG_NFS_V4_1 */ 641#endif /* CONFIG_NFS_V4_1 */
608 642
609static __be32 643static __be32
@@ -724,6 +758,7 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r
724 758
725 *hdr_res.status = status; 759 *hdr_res.status = status;
726 *hdr_res.nops = htonl(nops); 760 *hdr_res.nops = htonl(nops);
761 nfs4_cb_free_slot(cps.clp);
727 nfs_put_client(cps.clp); 762 nfs_put_client(cps.clp);
728 dprintk("%s: done, status = %u\n", __func__, ntohl(status)); 763 dprintk("%s: done, status = %u\n", __func__, ntohl(status));
729 return rpc_success; 764 return rpc_success;