aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@citi.umich.edu>2010-05-16 16:47:08 -0400
committerJ. Bruce Fields <bfields@redhat.com>2010-10-01 19:29:43 -0400
commit5878453dbde627a8e1b5a4693087e36cb88d45b1 (patch)
tree0cc34915aca412599363af87e59f16fb327a28a3 /fs/nfsd
parent1c8556026edac60368ceef446f0febc08014ba78 (diff)
nfsd4: generic callback code
Make the recall callback code more generic, so that other callbacks will be able to use it too. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfs4callback.c70
-rw-r--r--fs/nfsd/state.h2
2 files changed, 33 insertions, 39 deletions
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 5508e928fd9f..a037f26252ee 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -585,7 +585,6 @@ void nfsd4_probe_callback(struct nfs4_client *clp, struct nfs4_cb_conn *conn)
585static int nfsd41_cb_setup_sequence(struct nfs4_client *clp, 585static int nfsd41_cb_setup_sequence(struct nfs4_client *clp,
586 struct rpc_task *task) 586 struct rpc_task *task)
587{ 587{
588 struct nfsd4_cb_args *args = task->tk_msg.rpc_argp;
589 u32 *ptr = (u32 *)clp->cl_sessionid.data; 588 u32 *ptr = (u32 *)clp->cl_sessionid.data;
590 int status = 0; 589 int status = 0;
591 590
@@ -598,14 +597,6 @@ static int nfsd41_cb_setup_sequence(struct nfs4_client *clp,
598 status = -EAGAIN; 597 status = -EAGAIN;
599 goto out; 598 goto out;
600 } 599 }
601
602 /*
603 * We'll need the clp during XDR encoding and decoding,
604 * and the sequence during decoding to verify the reply
605 */
606 args->args_clp = clp;
607 task->tk_msg.rpc_resp = args;
608
609out: 600out:
610 dprintk("%s status=%d\n", __func__, status); 601 dprintk("%s status=%d\n", __func__, status);
611 return status; 602 return status;
@@ -617,7 +608,8 @@ out:
617 */ 608 */
618static void nfsd4_cb_prepare(struct rpc_task *task, void *calldata) 609static void nfsd4_cb_prepare(struct rpc_task *task, void *calldata)
619{ 610{
620 struct nfs4_delegation *dp = calldata; 611 struct nfsd4_callback *cb = calldata;
612 struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall);
621 struct nfs4_client *clp = dp->dl_client; 613 struct nfs4_client *clp = dp->dl_client;
622 struct nfsd4_cb_args *args = task->tk_msg.rpc_argp; 614 struct nfsd4_cb_args *args = task->tk_msg.rpc_argp;
623 u32 minorversion = clp->cl_cb_conn.cb_minorversion; 615 u32 minorversion = clp->cl_cb_conn.cb_minorversion;
@@ -640,7 +632,8 @@ static void nfsd4_cb_prepare(struct rpc_task *task, void *calldata)
640 632
641static void nfsd4_cb_done(struct rpc_task *task, void *calldata) 633static void nfsd4_cb_done(struct rpc_task *task, void *calldata)
642{ 634{
643 struct nfs4_delegation *dp = calldata; 635 struct nfsd4_callback *cb = calldata;
636 struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall);
644 struct nfs4_client *clp = dp->dl_client; 637 struct nfs4_client *clp = dp->dl_client;
645 638
646 dprintk("%s: minorversion=%d\n", __func__, 639 dprintk("%s: minorversion=%d\n", __func__,
@@ -662,7 +655,8 @@ static void nfsd4_cb_done(struct rpc_task *task, void *calldata)
662 655
663static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata) 656static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata)
664{ 657{
665 struct nfs4_delegation *dp = calldata; 658 struct nfsd4_callback *cb = calldata;
659 struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall);
666 struct nfs4_client *clp = dp->dl_client; 660 struct nfs4_client *clp = dp->dl_client;
667 struct rpc_clnt *current_rpc_client = clp->cl_cb_client; 661 struct rpc_clnt *current_rpc_client = clp->cl_cb_client;
668 662
@@ -707,7 +701,8 @@ static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata)
707 701
708static void nfsd4_cb_recall_release(void *calldata) 702static void nfsd4_cb_recall_release(void *calldata)
709{ 703{
710 struct nfs4_delegation *dp = calldata; 704 struct nfsd4_callback *cb = calldata;
705 struct nfs4_delegation *dp = container_of(cb, struct nfs4_delegation, dl_recall);
711 706
712 nfs4_put_delegation(dp); 707 nfs4_put_delegation(dp);
713} 708}
@@ -749,42 +744,39 @@ void nfsd4_set_callback_client(struct nfs4_client *clp, struct rpc_clnt *new)
749 rpc_shutdown_client(old); 744 rpc_shutdown_client(old);
750} 745}
751 746
752/* 747void nfsd4_release_cb(struct nfsd4_callback *cb)
753 * called with dp->dl_count inc'ed.
754 */
755static void _nfsd4_cb_recall(struct nfs4_delegation *dp)
756{ 748{
757 struct nfs4_client *clp = dp->dl_client; 749 if (cb->cb_ops->rpc_release)
750 cb->cb_ops->rpc_release(cb);
751}
752
753void nfsd4_do_callback_rpc(struct work_struct *w)
754{
755 struct nfsd4_callback *cb = container_of(w, struct nfsd4_callback, cb_work);
756 struct nfs4_client *clp = cb->cb_args.args_clp;
758 struct rpc_clnt *clnt = clp->cl_cb_client; 757 struct rpc_clnt *clnt = clp->cl_cb_client;
759 struct nfsd4_cb_args *args = &dp->dl_recall.cb_args;
760 struct rpc_message msg = {
761 .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_RECALL],
762 .rpc_cred = callback_cred
763 };
764 758
765 if (clnt == NULL) { 759 if (clnt == NULL) {
766 nfs4_put_delegation(dp); 760 nfsd4_release_cb(cb);
767 return; /* Client is shutting down; give up. */ 761 return; /* Client is shutting down; give up. */
768 } 762 }
769 763 rpc_call_async(clnt, &cb->cb_msg, RPC_TASK_SOFT, cb->cb_ops, cb);
770 args->args_op = dp;
771 msg.rpc_argp = args;
772 dp->dl_retries = 1;
773 rpc_call_async(clnt, &msg, RPC_TASK_SOFT, &nfsd4_cb_recall_ops, dp);
774} 764}
775 765
776void nfsd4_do_callback_rpc(struct work_struct *w) 766void nfsd4_cb_recall(struct nfs4_delegation *dp)
777{ 767{
778 /* XXX: for now, just send off delegation recall. */ 768 struct nfsd4_callback *cb = &dp->dl_recall;
779 /* In future, generalize to handle any sort of callback. */
780 struct nfsd4_callback *c = container_of(w, struct nfsd4_callback, cb_work);
781 struct nfs4_delegation *dp = container_of(c, struct nfs4_delegation, dl_recall);
782
783 _nfsd4_cb_recall(dp);
784}
785 769
770 dp->dl_retries = 1;
771 cb->cb_args.args_op = dp;
772 cb->cb_args.args_clp = dp->dl_client;
773 cb->cb_msg.rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_RECALL];
774 cb->cb_msg.rpc_argp = &cb->cb_args;
775 cb->cb_msg.rpc_resp = &cb->cb_args;
776 cb->cb_msg.rpc_cred = callback_cred;
777
778 cb->cb_ops = &nfsd4_cb_recall_ops;
779 dp->dl_retries = 1;
786 780
787void nfsd4_cb_recall(struct nfs4_delegation *dp)
788{
789 queue_work(callback_wq, &dp->dl_recall.cb_work); 781 queue_work(callback_wq, &dp->dl_recall.cb_work);
790} 782}
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index f988b90ec213..6e592148ad80 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -72,6 +72,8 @@ struct nfsd4_cb_args {
72 72
73struct nfsd4_callback { 73struct nfsd4_callback {
74 struct nfsd4_cb_args cb_args; 74 struct nfsd4_cb_args cb_args;
75 struct rpc_message cb_msg;
76 const struct rpc_call_ops *cb_ops;
75 struct work_struct cb_work; 77 struct work_struct cb_work;
76}; 78};
77 79