aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2010-07-31 14:29:08 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2010-08-04 08:54:07 -0400
commit58f9612c6ea858f532021a0ce42ec53cb0a493b3 (patch)
tree9466a16cd79c547fddcec5bd598d8097ae9a3859
parentd9b6cd94601e1d17273f93a326a135fbf487a918 (diff)
SUNRPC: Move remaining RPC client related task initialisation into clnt.c
Now that rpc_run_task() is the sole entry point for RPC calls, we can move the remaining rpc_client-related initialisation of struct rpc_task from sched.c into clnt.c. Also move rpc_killall_tasks() into the same file, since that too is relative to the rpc_clnt. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--include/linux/sunrpc/clnt.h1
-rw-r--r--net/sunrpc/clnt.c84
-rw-r--r--net/sunrpc/sched.c77
3 files changed, 89 insertions, 73 deletions
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index debe75532199..569dc722a600 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -131,6 +131,7 @@ struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *,
131struct rpc_clnt *rpc_clone_client(struct rpc_clnt *); 131struct rpc_clnt *rpc_clone_client(struct rpc_clnt *);
132void rpc_shutdown_client(struct rpc_clnt *); 132void rpc_shutdown_client(struct rpc_clnt *);
133void rpc_release_client(struct rpc_clnt *); 133void rpc_release_client(struct rpc_clnt *);
134void rpc_task_release_client(struct rpc_task *);
134 135
135int rpcb_register(u32, u32, int, unsigned short); 136int rpcb_register(u32, u32, int, unsigned short);
136int rpcb_v4_register(const u32 program, const u32 version, 137int rpcb_v4_register(const u32 program, const u32 version,
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 234c40c15f69..3647c81fd689 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -414,6 +414,35 @@ out_no_clnt:
414EXPORT_SYMBOL_GPL(rpc_clone_client); 414EXPORT_SYMBOL_GPL(rpc_clone_client);
415 415
416/* 416/*
417 * Kill all tasks for the given client.
418 * XXX: kill their descendants as well?
419 */
420void rpc_killall_tasks(struct rpc_clnt *clnt)
421{
422 struct rpc_task *rovr;
423
424
425 if (list_empty(&clnt->cl_tasks))
426 return;
427 dprintk("RPC: killing all tasks for client %p\n", clnt);
428 /*
429 * Spin lock all_tasks to prevent changes...
430 */
431 spin_lock(&clnt->cl_lock);
432 list_for_each_entry(rovr, &clnt->cl_tasks, tk_task) {
433 if (!RPC_IS_ACTIVATED(rovr))
434 continue;
435 if (!(rovr->tk_flags & RPC_TASK_KILLED)) {
436 rovr->tk_flags |= RPC_TASK_KILLED;
437 rpc_exit(rovr, -EIO);
438 rpc_wake_up_queued_task(rovr->tk_waitqueue, rovr);
439 }
440 }
441 spin_unlock(&clnt->cl_lock);
442}
443EXPORT_SYMBOL_GPL(rpc_killall_tasks);
444
445/*
417 * Properly shut down an RPC client, terminating all outstanding 446 * Properly shut down an RPC client, terminating all outstanding
418 * requests. 447 * requests.
419 */ 448 */
@@ -538,6 +567,49 @@ out:
538} 567}
539EXPORT_SYMBOL_GPL(rpc_bind_new_program); 568EXPORT_SYMBOL_GPL(rpc_bind_new_program);
540 569
570void rpc_task_release_client(struct rpc_task *task)
571{
572 struct rpc_clnt *clnt = task->tk_client;
573
574 if (clnt != NULL) {
575 /* Remove from client task list */
576 spin_lock(&clnt->cl_lock);
577 list_del(&task->tk_task);
578 spin_unlock(&clnt->cl_lock);
579 task->tk_client = NULL;
580
581 rpc_release_client(clnt);
582 }
583}
584
585static
586void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt)
587{
588 if (clnt != NULL) {
589 rpc_task_release_client(task);
590 task->tk_client = clnt;
591 kref_get(&clnt->cl_kref);
592 if (clnt->cl_softrtry)
593 task->tk_flags |= RPC_TASK_SOFT;
594 /* Add to the client's list of all tasks */
595 spin_lock(&clnt->cl_lock);
596 list_add_tail(&task->tk_task, &clnt->cl_tasks);
597 spin_unlock(&clnt->cl_lock);
598 }
599}
600
601static void
602rpc_task_set_rpc_message(struct rpc_task *task, const struct rpc_message *msg)
603{
604 if (msg != NULL) {
605 task->tk_msg.rpc_proc = msg->rpc_proc;
606 task->tk_msg.rpc_argp = msg->rpc_argp;
607 task->tk_msg.rpc_resp = msg->rpc_resp;
608 /* Bind the user cred */
609 rpcauth_bindcred(task, msg->rpc_cred, task->tk_flags);
610 }
611}
612
541/* 613/*
542 * Default callback for async RPC calls 614 * Default callback for async RPC calls
543 */ 615 */
@@ -562,6 +634,18 @@ struct rpc_task *rpc_run_task(const struct rpc_task_setup *task_setup_data)
562 if (IS_ERR(task)) 634 if (IS_ERR(task))
563 goto out; 635 goto out;
564 636
637 rpc_task_set_client(task, task_setup_data->rpc_client);
638 rpc_task_set_rpc_message(task, task_setup_data->rpc_message);
639
640 if (task->tk_status != 0) {
641 int ret = task->tk_status;
642 rpc_put_task(task);
643 return ERR_PTR(ret);
644 }
645
646 if (task->tk_action == NULL)
647 rpc_call_start(task);
648
565 atomic_inc(&task->tk_count); 649 atomic_inc(&task->tk_count);
566 rpc_execute(task); 650 rpc_execute(task);
567out: 651out:
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 37452762af70..a42296db2ecd 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -246,17 +246,8 @@ static inline void rpc_task_set_debuginfo(struct rpc_task *task)
246 246
247static void rpc_set_active(struct rpc_task *task) 247static void rpc_set_active(struct rpc_task *task)
248{ 248{
249 struct rpc_clnt *clnt;
250 if (test_and_set_bit(RPC_TASK_ACTIVE, &task->tk_runstate) != 0)
251 return;
252 rpc_task_set_debuginfo(task); 249 rpc_task_set_debuginfo(task);
253 /* Add to global list of all tasks */ 250 set_bit(RPC_TASK_ACTIVE, &task->tk_runstate);
254 clnt = task->tk_client;
255 if (clnt != NULL) {
256 spin_lock(&clnt->cl_lock);
257 list_add_tail(&task->tk_task, &clnt->cl_tasks);
258 spin_unlock(&clnt->cl_lock);
259 }
260} 251}
261 252
262/* 253/*
@@ -319,11 +310,6 @@ static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
319 dprintk("RPC: %5u sleep_on(queue \"%s\" time %lu)\n", 310 dprintk("RPC: %5u sleep_on(queue \"%s\" time %lu)\n",
320 task->tk_pid, rpc_qname(q), jiffies); 311 task->tk_pid, rpc_qname(q), jiffies);
321 312
322 if (!RPC_IS_ASYNC(task) && !RPC_IS_ACTIVATED(task)) {
323 printk(KERN_ERR "RPC: Inactive synchronous task put to sleep!\n");
324 return;
325 }
326
327 __rpc_add_wait_queue(q, task); 313 __rpc_add_wait_queue(q, task);
328 314
329 BUG_ON(task->tk_callback != NULL); 315 BUG_ON(task->tk_callback != NULL);
@@ -334,8 +320,8 @@ static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
334void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, 320void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
335 rpc_action action) 321 rpc_action action)
336{ 322{
337 /* Mark the task as being activated if so needed */ 323 /* We shouldn't ever put an inactive task to sleep */
338 rpc_set_active(task); 324 BUG_ON(!RPC_IS_ACTIVATED(task));
339 325
340 /* 326 /*
341 * Protect the queue operations. 327 * Protect the queue operations.
@@ -807,26 +793,9 @@ static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *ta
807 /* Initialize workqueue for async tasks */ 793 /* Initialize workqueue for async tasks */
808 task->tk_workqueue = task_setup_data->workqueue; 794 task->tk_workqueue = task_setup_data->workqueue;
809 795
810 task->tk_client = task_setup_data->rpc_client;
811 if (task->tk_client != NULL) {
812 kref_get(&task->tk_client->cl_kref);
813 if (task->tk_client->cl_softrtry)
814 task->tk_flags |= RPC_TASK_SOFT;
815 }
816
817 if (task->tk_ops->rpc_call_prepare != NULL) 796 if (task->tk_ops->rpc_call_prepare != NULL)
818 task->tk_action = rpc_prepare_task; 797 task->tk_action = rpc_prepare_task;
819 798
820 if (task_setup_data->rpc_message != NULL) {
821 task->tk_msg.rpc_proc = task_setup_data->rpc_message->rpc_proc;
822 task->tk_msg.rpc_argp = task_setup_data->rpc_message->rpc_argp;
823 task->tk_msg.rpc_resp = task_setup_data->rpc_message->rpc_resp;
824 /* Bind the user cred */
825 rpcauth_bindcred(task, task_setup_data->rpc_message->rpc_cred, task_setup_data->flags);
826 if (task->tk_action == NULL)
827 rpc_call_start(task);
828 }
829
830 /* starting timestamp */ 799 /* starting timestamp */
831 task->tk_start = ktime_get(); 800 task->tk_start = ktime_get();
832 801
@@ -896,10 +865,7 @@ void rpc_put_task(struct rpc_task *task)
896 xprt_release(task); 865 xprt_release(task);
897 if (task->tk_msg.rpc_cred) 866 if (task->tk_msg.rpc_cred)
898 rpcauth_unbindcred(task); 867 rpcauth_unbindcred(task);
899 if (task->tk_client) { 868 rpc_task_release_client(task);
900 rpc_release_client(task->tk_client);
901 task->tk_client = NULL;
902 }
903 if (task->tk_workqueue != NULL) { 869 if (task->tk_workqueue != NULL) {
904 INIT_WORK(&task->u.tk_work, rpc_async_release); 870 INIT_WORK(&task->u.tk_work, rpc_async_release);
905 queue_work(task->tk_workqueue, &task->u.tk_work); 871 queue_work(task->tk_workqueue, &task->u.tk_work);
@@ -912,13 +878,6 @@ static void rpc_release_task(struct rpc_task *task)
912{ 878{
913 dprintk("RPC: %5u release task\n", task->tk_pid); 879 dprintk("RPC: %5u release task\n", task->tk_pid);
914 880
915 if (!list_empty(&task->tk_task)) {
916 struct rpc_clnt *clnt = task->tk_client;
917 /* Remove from client task list */
918 spin_lock(&clnt->cl_lock);
919 list_del(&task->tk_task);
920 spin_unlock(&clnt->cl_lock);
921 }
922 BUG_ON (RPC_IS_QUEUED(task)); 881 BUG_ON (RPC_IS_QUEUED(task));
923 882
924 /* Wake up anyone who is waiting for task completion */ 883 /* Wake up anyone who is waiting for task completion */
@@ -927,34 +886,6 @@ static void rpc_release_task(struct rpc_task *task)
927 rpc_put_task(task); 886 rpc_put_task(task);
928} 887}
929 888
930/*
931 * Kill all tasks for the given client.
932 * XXX: kill their descendants as well?
933 */
934void rpc_killall_tasks(struct rpc_clnt *clnt)
935{
936 struct rpc_task *rovr;
937
938
939 if (list_empty(&clnt->cl_tasks))
940 return;
941 dprintk("RPC: killing all tasks for client %p\n", clnt);
942 /*
943 * Spin lock all_tasks to prevent changes...
944 */
945 spin_lock(&clnt->cl_lock);
946 list_for_each_entry(rovr, &clnt->cl_tasks, tk_task) {
947 if (! RPC_IS_ACTIVATED(rovr))
948 continue;
949 if (!(rovr->tk_flags & RPC_TASK_KILLED)) {
950 rovr->tk_flags |= RPC_TASK_KILLED;
951 rpc_exit(rovr, -EIO);
952 }
953 }
954 spin_unlock(&clnt->cl_lock);
955}
956EXPORT_SYMBOL_GPL(rpc_killall_tasks);
957
958int rpciod_up(void) 889int rpciod_up(void)
959{ 890{
960 return try_module_get(THIS_MODULE) ? 0 : -EINVAL; 891 return try_module_get(THIS_MODULE) ? 0 : -EINVAL;