diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-01-03 03:55:04 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-01-06 14:58:39 -0500 |
commit | 963d8fe53339128ee46a7701f2e36305f0ccff8c (patch) | |
tree | 426736c70a8e05cb1d945d5c7f44ea6475edd113 /net/sunrpc/sched.c | |
parent | abbcf28f23d53e8ec56a91f3528743913fa2694a (diff) |
RPC: Clean up RPC task structure
Shrink the RPC task structure. Instead of storing separate pointers
for task->tk_exit and task->tk_release, put them in a structure.
Also pass the user data pointer as a parameter instead of passing it via
task->tk_calldata. This enables us to nest callbacks.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/sched.c')
-rw-r--r-- | net/sunrpc/sched.c | 53 |
1 files changed, 28 insertions, 25 deletions
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 3fcf7b0e1f6c..8d6233d3248b 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c | |||
@@ -555,13 +555,13 @@ __rpc_atrun(struct rpc_task *task) | |||
555 | } | 555 | } |
556 | 556 | ||
557 | /* | 557 | /* |
558 | * Helper that calls task->tk_exit if it exists | 558 | * Helper that calls task->tk_ops->rpc_call_done if it exists |
559 | */ | 559 | */ |
560 | void rpc_exit_task(struct rpc_task *task) | 560 | void rpc_exit_task(struct rpc_task *task) |
561 | { | 561 | { |
562 | task->tk_action = NULL; | 562 | task->tk_action = NULL; |
563 | if (task->tk_exit != NULL) { | 563 | if (task->tk_ops->rpc_call_done != NULL) { |
564 | task->tk_exit(task); | 564 | task->tk_ops->rpc_call_done(task, task->tk_calldata); |
565 | if (task->tk_action != NULL) { | 565 | if (task->tk_action != NULL) { |
566 | WARN_ON(RPC_ASSASSINATED(task)); | 566 | WARN_ON(RPC_ASSASSINATED(task)); |
567 | /* Always release the RPC slot and buffer memory */ | 567 | /* Always release the RPC slot and buffer memory */ |
@@ -747,7 +747,7 @@ rpc_free(struct rpc_task *task) | |||
747 | /* | 747 | /* |
748 | * Creation and deletion of RPC task structures | 748 | * Creation and deletion of RPC task structures |
749 | */ | 749 | */ |
750 | void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, rpc_action callback, int flags) | 750 | void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, int flags, const struct rpc_call_ops *tk_ops, void *calldata) |
751 | { | 751 | { |
752 | memset(task, 0, sizeof(*task)); | 752 | memset(task, 0, sizeof(*task)); |
753 | init_timer(&task->tk_timer); | 753 | init_timer(&task->tk_timer); |
@@ -755,7 +755,8 @@ void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, rpc_action call | |||
755 | task->tk_timer.function = (void (*)(unsigned long)) rpc_run_timer; | 755 | task->tk_timer.function = (void (*)(unsigned long)) rpc_run_timer; |
756 | task->tk_client = clnt; | 756 | task->tk_client = clnt; |
757 | task->tk_flags = flags; | 757 | task->tk_flags = flags; |
758 | task->tk_exit = callback; | 758 | task->tk_ops = tk_ops; |
759 | task->tk_calldata = calldata; | ||
759 | 760 | ||
760 | /* Initialize retry counters */ | 761 | /* Initialize retry counters */ |
761 | task->tk_garb_retry = 2; | 762 | task->tk_garb_retry = 2; |
@@ -784,6 +785,8 @@ void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, rpc_action call | |||
784 | list_add_tail(&task->tk_task, &all_tasks); | 785 | list_add_tail(&task->tk_task, &all_tasks); |
785 | spin_unlock(&rpc_sched_lock); | 786 | spin_unlock(&rpc_sched_lock); |
786 | 787 | ||
788 | BUG_ON(task->tk_ops == NULL); | ||
789 | |||
787 | dprintk("RPC: %4d new task procpid %d\n", task->tk_pid, | 790 | dprintk("RPC: %4d new task procpid %d\n", task->tk_pid, |
788 | current->pid); | 791 | current->pid); |
789 | } | 792 | } |
@@ -794,8 +797,7 @@ rpc_alloc_task(void) | |||
794 | return (struct rpc_task *)mempool_alloc(rpc_task_mempool, GFP_NOFS); | 797 | return (struct rpc_task *)mempool_alloc(rpc_task_mempool, GFP_NOFS); |
795 | } | 798 | } |
796 | 799 | ||
797 | static void | 800 | static void rpc_free_task(struct rpc_task *task) |
798 | rpc_default_free_task(struct rpc_task *task) | ||
799 | { | 801 | { |
800 | dprintk("RPC: %4d freeing task\n", task->tk_pid); | 802 | dprintk("RPC: %4d freeing task\n", task->tk_pid); |
801 | mempool_free(task, rpc_task_mempool); | 803 | mempool_free(task, rpc_task_mempool); |
@@ -806,8 +808,7 @@ rpc_default_free_task(struct rpc_task *task) | |||
806 | * clean up after an allocation failure, as the client may | 808 | * clean up after an allocation failure, as the client may |
807 | * have specified "oneshot". | 809 | * have specified "oneshot". |
808 | */ | 810 | */ |
809 | struct rpc_task * | 811 | struct rpc_task *rpc_new_task(struct rpc_clnt *clnt, int flags, const struct rpc_call_ops *tk_ops, void *calldata) |
810 | rpc_new_task(struct rpc_clnt *clnt, rpc_action callback, int flags) | ||
811 | { | 812 | { |
812 | struct rpc_task *task; | 813 | struct rpc_task *task; |
813 | 814 | ||
@@ -815,10 +816,7 @@ rpc_new_task(struct rpc_clnt *clnt, rpc_action callback, int flags) | |||
815 | if (!task) | 816 | if (!task) |
816 | goto cleanup; | 817 | goto cleanup; |
817 | 818 | ||
818 | rpc_init_task(task, clnt, callback, flags); | 819 | rpc_init_task(task, clnt, flags, tk_ops, calldata); |
819 | |||
820 | /* Replace tk_release */ | ||
821 | task->tk_release = rpc_default_free_task; | ||
822 | 820 | ||
823 | dprintk("RPC: %4d allocated task\n", task->tk_pid); | 821 | dprintk("RPC: %4d allocated task\n", task->tk_pid); |
824 | task->tk_flags |= RPC_TASK_DYNAMIC; | 822 | task->tk_flags |= RPC_TASK_DYNAMIC; |
@@ -838,6 +836,8 @@ cleanup: | |||
838 | 836 | ||
839 | void rpc_release_task(struct rpc_task *task) | 837 | void rpc_release_task(struct rpc_task *task) |
840 | { | 838 | { |
839 | const struct rpc_call_ops *tk_ops = task->tk_ops; | ||
840 | void *calldata = task->tk_calldata; | ||
841 | dprintk("RPC: %4d release task\n", task->tk_pid); | 841 | dprintk("RPC: %4d release task\n", task->tk_pid); |
842 | 842 | ||
843 | #ifdef RPC_DEBUG | 843 | #ifdef RPC_DEBUG |
@@ -869,8 +869,10 @@ void rpc_release_task(struct rpc_task *task) | |||
869 | #ifdef RPC_DEBUG | 869 | #ifdef RPC_DEBUG |
870 | task->tk_magic = 0; | 870 | task->tk_magic = 0; |
871 | #endif | 871 | #endif |
872 | if (task->tk_release) | 872 | if (task->tk_flags & RPC_TASK_DYNAMIC) |
873 | task->tk_release(task); | 873 | rpc_free_task(task); |
874 | if (tk_ops->rpc_release) | ||
875 | tk_ops->rpc_release(calldata); | ||
874 | } | 876 | } |
875 | 877 | ||
876 | /** | 878 | /** |
@@ -883,12 +885,11 @@ void rpc_release_task(struct rpc_task *task) | |||
883 | * | 885 | * |
884 | * Caller must hold childq.lock | 886 | * Caller must hold childq.lock |
885 | */ | 887 | */ |
886 | static inline struct rpc_task *rpc_find_parent(struct rpc_task *child) | 888 | static inline struct rpc_task *rpc_find_parent(struct rpc_task *child, struct rpc_task *parent) |
887 | { | 889 | { |
888 | struct rpc_task *task, *parent; | 890 | struct rpc_task *task; |
889 | struct list_head *le; | 891 | struct list_head *le; |
890 | 892 | ||
891 | parent = (struct rpc_task *) child->tk_calldata; | ||
892 | task_for_each(task, le, &childq.tasks[0]) | 893 | task_for_each(task, le, &childq.tasks[0]) |
893 | if (task == parent) | 894 | if (task == parent) |
894 | return parent; | 895 | return parent; |
@@ -896,18 +897,22 @@ static inline struct rpc_task *rpc_find_parent(struct rpc_task *child) | |||
896 | return NULL; | 897 | return NULL; |
897 | } | 898 | } |
898 | 899 | ||
899 | static void rpc_child_exit(struct rpc_task *child) | 900 | static void rpc_child_exit(struct rpc_task *child, void *calldata) |
900 | { | 901 | { |
901 | struct rpc_task *parent; | 902 | struct rpc_task *parent; |
902 | 903 | ||
903 | spin_lock_bh(&childq.lock); | 904 | spin_lock_bh(&childq.lock); |
904 | if ((parent = rpc_find_parent(child)) != NULL) { | 905 | if ((parent = rpc_find_parent(child, calldata)) != NULL) { |
905 | parent->tk_status = child->tk_status; | 906 | parent->tk_status = child->tk_status; |
906 | __rpc_wake_up_task(parent); | 907 | __rpc_wake_up_task(parent); |
907 | } | 908 | } |
908 | spin_unlock_bh(&childq.lock); | 909 | spin_unlock_bh(&childq.lock); |
909 | } | 910 | } |
910 | 911 | ||
912 | static const struct rpc_call_ops rpc_child_ops = { | ||
913 | .rpc_call_done = rpc_child_exit, | ||
914 | }; | ||
915 | |||
911 | /* | 916 | /* |
912 | * Note: rpc_new_task releases the client after a failure. | 917 | * Note: rpc_new_task releases the client after a failure. |
913 | */ | 918 | */ |
@@ -916,11 +921,9 @@ rpc_new_child(struct rpc_clnt *clnt, struct rpc_task *parent) | |||
916 | { | 921 | { |
917 | struct rpc_task *task; | 922 | struct rpc_task *task; |
918 | 923 | ||
919 | task = rpc_new_task(clnt, NULL, RPC_TASK_ASYNC | RPC_TASK_CHILD); | 924 | task = rpc_new_task(clnt, RPC_TASK_ASYNC | RPC_TASK_CHILD, &rpc_child_ops, parent); |
920 | if (!task) | 925 | if (!task) |
921 | goto fail; | 926 | goto fail; |
922 | task->tk_exit = rpc_child_exit; | ||
923 | task->tk_calldata = parent; | ||
924 | return task; | 927 | return task; |
925 | 928 | ||
926 | fail: | 929 | fail: |
@@ -1056,7 +1059,7 @@ void rpc_show_tasks(void) | |||
1056 | return; | 1059 | return; |
1057 | } | 1060 | } |
1058 | printk("-pid- proc flgs status -client- -prog- --rqstp- -timeout " | 1061 | printk("-pid- proc flgs status -client- -prog- --rqstp- -timeout " |
1059 | "-rpcwait -action- --exit--\n"); | 1062 | "-rpcwait -action- ---ops--\n"); |
1060 | alltask_for_each(t, le, &all_tasks) { | 1063 | alltask_for_each(t, le, &all_tasks) { |
1061 | const char *rpc_waitq = "none"; | 1064 | const char *rpc_waitq = "none"; |
1062 | 1065 | ||
@@ -1071,7 +1074,7 @@ void rpc_show_tasks(void) | |||
1071 | (t->tk_client ? t->tk_client->cl_prog : 0), | 1074 | (t->tk_client ? t->tk_client->cl_prog : 0), |
1072 | t->tk_rqstp, t->tk_timeout, | 1075 | t->tk_rqstp, t->tk_timeout, |
1073 | rpc_waitq, | 1076 | rpc_waitq, |
1074 | t->tk_action, t->tk_exit); | 1077 | t->tk_action, t->tk_ops); |
1075 | } | 1078 | } |
1076 | spin_unlock(&rpc_sched_lock); | 1079 | spin_unlock(&rpc_sched_lock); |
1077 | } | 1080 | } |