diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-07-31 14:29:08 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-08-04 08:54:07 -0400 |
commit | 58f9612c6ea858f532021a0ce42ec53cb0a493b3 (patch) | |
tree | 9466a16cd79c547fddcec5bd598d8097ae9a3859 | |
parent | d9b6cd94601e1d17273f93a326a135fbf487a918 (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.h | 1 | ||||
-rw-r--r-- | net/sunrpc/clnt.c | 84 | ||||
-rw-r--r-- | net/sunrpc/sched.c | 77 |
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 *, | |||
131 | struct rpc_clnt *rpc_clone_client(struct rpc_clnt *); | 131 | struct rpc_clnt *rpc_clone_client(struct rpc_clnt *); |
132 | void rpc_shutdown_client(struct rpc_clnt *); | 132 | void rpc_shutdown_client(struct rpc_clnt *); |
133 | void rpc_release_client(struct rpc_clnt *); | 133 | void rpc_release_client(struct rpc_clnt *); |
134 | void rpc_task_release_client(struct rpc_task *); | ||
134 | 135 | ||
135 | int rpcb_register(u32, u32, int, unsigned short); | 136 | int rpcb_register(u32, u32, int, unsigned short); |
136 | int rpcb_v4_register(const u32 program, const u32 version, | 137 | int 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: | |||
414 | EXPORT_SYMBOL_GPL(rpc_clone_client); | 414 | EXPORT_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 | */ | ||
420 | void 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 | } | ||
443 | EXPORT_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 | } |
539 | EXPORT_SYMBOL_GPL(rpc_bind_new_program); | 568 | EXPORT_SYMBOL_GPL(rpc_bind_new_program); |
540 | 569 | ||
570 | void 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 | |||
585 | static | ||
586 | void 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 | |||
601 | static void | ||
602 | rpc_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); |
567 | out: | 651 | out: |
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 | ||
247 | static void rpc_set_active(struct rpc_task *task) | 247 | static 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, | |||
334 | void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, | 320 | void 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 | */ | ||
934 | void 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 | } | ||
956 | EXPORT_SYMBOL_GPL(rpc_killall_tasks); | ||
957 | |||
958 | int rpciod_up(void) | 889 | int rpciod_up(void) |
959 | { | 890 | { |
960 | return try_module_get(THIS_MODULE) ? 0 : -EINVAL; | 891 | return try_module_get(THIS_MODULE) ? 0 : -EINVAL; |