aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@citi.umich.edu>2010-05-26 17:52:14 -0400
committerJ. Bruce Fields <bfields@redhat.com>2010-10-01 19:29:43 -0400
commitcee277d92495a9ea49a6137fe7005d7c76b31b5b (patch)
treec7e80e31d64038d17761472d9a349330426d8c12 /fs
parent5878453dbde627a8e1b5a4693087e36cb88d45b1 (diff)
nfsd4: use generic callback code in null case
This will eventually allow us, for example, to kick off null callback from contexts where we can't sleep. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfsd/nfs4callback.c33
-rw-r--r--fs/nfsd/nfs4state.c1
-rw-r--r--fs/nfsd/state.h1
3 files changed, 20 insertions, 15 deletions
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index a037f26252ee..26fa878005cc 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -519,7 +519,7 @@ static void warn_no_callback_path(struct nfs4_client *clp, int reason)
519 519
520static void nfsd4_cb_probe_done(struct rpc_task *task, void *calldata) 520static void nfsd4_cb_probe_done(struct rpc_task *task, void *calldata)
521{ 521{
522 struct nfs4_client *clp = calldata; 522 struct nfs4_client *clp = container_of(calldata, struct nfs4_client, cl_cb_null);
523 523
524 if (task->tk_status) 524 if (task->tk_status)
525 warn_no_callback_path(clp, task->tk_status); 525 warn_no_callback_path(clp, task->tk_status);
@@ -528,6 +528,8 @@ static void nfsd4_cb_probe_done(struct rpc_task *task, void *calldata)
528} 528}
529 529
530static const struct rpc_call_ops nfsd4_cb_probe_ops = { 530static const struct rpc_call_ops nfsd4_cb_probe_ops = {
531 /* XXX: release method to ensure we set the cb channel down if
532 * necessary on early failure? */
531 .rpc_call_done = nfsd4_cb_probe_done, 533 .rpc_call_done = nfsd4_cb_probe_done,
532}; 534};
533 535
@@ -543,21 +545,23 @@ int set_callback_cred(void)
543 return 0; 545 return 0;
544} 546}
545 547
548static struct workqueue_struct *callback_wq;
546 549
547void do_probe_callback(struct nfs4_client *clp) 550void do_probe_callback(struct nfs4_client *clp)
548{ 551{
549 struct rpc_message msg = { 552 struct nfsd4_callback *cb = &clp->cl_cb_null;
550 .rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL],
551 .rpc_argp = clp,
552 .rpc_cred = callback_cred
553 };
554 int status;
555 553
556 status = rpc_call_async(clp->cl_cb_client, &msg, 554 cb->cb_args.args_op = NULL;
557 RPC_TASK_SOFT | RPC_TASK_SOFTCONN, 555 cb->cb_args.args_clp = clp;
558 &nfsd4_cb_probe_ops, (void *)clp); 556
559 if (status) 557 cb->cb_msg.rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_NULL];
560 warn_no_callback_path(clp, status); 558 cb->cb_msg.rpc_argp = NULL;
559 cb->cb_msg.rpc_resp = NULL;
560 cb->cb_msg.rpc_cred = callback_cred;
561
562 cb->cb_ops = &nfsd4_cb_probe_ops;
563
564 queue_work(callback_wq, &cb->cb_work);
561} 565}
562 566
563/* 567/*
@@ -713,8 +717,6 @@ static const struct rpc_call_ops nfsd4_cb_recall_ops = {
713 .rpc_release = nfsd4_cb_recall_release, 717 .rpc_release = nfsd4_cb_recall_release,
714}; 718};
715 719
716static struct workqueue_struct *callback_wq;
717
718int nfsd4_create_callback_queue(void) 720int nfsd4_create_callback_queue(void)
719{ 721{
720 callback_wq = create_singlethread_workqueue("nfsd4_callbacks"); 722 callback_wq = create_singlethread_workqueue("nfsd4_callbacks");
@@ -760,7 +762,8 @@ void nfsd4_do_callback_rpc(struct work_struct *w)
760 nfsd4_release_cb(cb); 762 nfsd4_release_cb(cb);
761 return; /* Client is shutting down; give up. */ 763 return; /* Client is shutting down; give up. */
762 } 764 }
763 rpc_call_async(clnt, &cb->cb_msg, RPC_TASK_SOFT, cb->cb_ops, cb); 765 rpc_call_async(clnt, &cb->cb_msg, RPC_TASK_SOFT | RPC_TASK_SOFTCONN,
766 cb->cb_ops, cb);
764} 767}
765 768
766void nfsd4_cb_recall(struct nfs4_delegation *dp) 769void nfsd4_cb_recall(struct nfs4_delegation *dp)
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index d347180ce55a..2f464fb26afc 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -978,6 +978,7 @@ static struct nfs4_client *create_client(struct xdr_netobj name, char *recdir,
978 INIT_LIST_HEAD(&clp->cl_delegations); 978 INIT_LIST_HEAD(&clp->cl_delegations);
979 INIT_LIST_HEAD(&clp->cl_sessions); 979 INIT_LIST_HEAD(&clp->cl_sessions);
980 INIT_LIST_HEAD(&clp->cl_lru); 980 INIT_LIST_HEAD(&clp->cl_lru);
981 INIT_WORK(&clp->cl_cb_null.cb_work, nfsd4_do_callback_rpc);
981 clp->cl_time = get_seconds(); 982 clp->cl_time = get_seconds();
982 clear_bit(0, &clp->cl_cb_slot_busy); 983 clear_bit(0, &clp->cl_cb_slot_busy);
983 rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table"); 984 rpc_init_wait_queue(&clp->cl_cb_waitq, "Backchannel slot table");
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index 6e592148ad80..19732d531cda 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -223,6 +223,7 @@ struct nfs4_client {
223 struct nfs4_cb_conn cl_cb_conn; 223 struct nfs4_cb_conn cl_cb_conn;
224 struct rpc_clnt *cl_cb_client; 224 struct rpc_clnt *cl_cb_client;
225 atomic_t cl_cb_set; 225 atomic_t cl_cb_set;
226 struct nfsd4_callback cl_cb_null;
226 227
227 /* for nfs41 */ 228 /* for nfs41 */
228 struct list_head cl_sessions; 229 struct list_head cl_sessions;