aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc')
-rw-r--r--net/sunrpc/clnt.c15
-rw-r--r--net/sunrpc/sched.c53
2 files changed, 36 insertions, 32 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 6ab4cbd8a901..8b2f75bc006d 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -374,10 +374,14 @@ out:
374 * Default callback for async RPC calls 374 * Default callback for async RPC calls
375 */ 375 */
376static void 376static void
377rpc_default_callback(struct rpc_task *task) 377rpc_default_callback(struct rpc_task *task, void *data)
378{ 378{
379} 379}
380 380
381static const struct rpc_call_ops rpc_default_ops = {
382 .rpc_call_done = rpc_default_callback,
383};
384
381/* 385/*
382 * Export the signal mask handling for synchronous code that 386 * Export the signal mask handling for synchronous code that
383 * sleeps on RPC calls 387 * sleeps on RPC calls
@@ -432,7 +436,7 @@ int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
432 BUG_ON(flags & RPC_TASK_ASYNC); 436 BUG_ON(flags & RPC_TASK_ASYNC);
433 437
434 status = -ENOMEM; 438 status = -ENOMEM;
435 task = rpc_new_task(clnt, NULL, flags); 439 task = rpc_new_task(clnt, flags, &rpc_default_ops, NULL);
436 if (task == NULL) 440 if (task == NULL)
437 goto out; 441 goto out;
438 442
@@ -459,7 +463,7 @@ out:
459 */ 463 */
460int 464int
461rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags, 465rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
462 rpc_action callback, void *data) 466 const struct rpc_call_ops *tk_ops, void *data)
463{ 467{
464 struct rpc_task *task; 468 struct rpc_task *task;
465 sigset_t oldset; 469 sigset_t oldset;
@@ -472,12 +476,9 @@ rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
472 flags |= RPC_TASK_ASYNC; 476 flags |= RPC_TASK_ASYNC;
473 477
474 /* Create/initialize a new RPC task */ 478 /* Create/initialize a new RPC task */
475 if (!callback)
476 callback = rpc_default_callback;
477 status = -ENOMEM; 479 status = -ENOMEM;
478 if (!(task = rpc_new_task(clnt, callback, flags))) 480 if (!(task = rpc_new_task(clnt, flags, tk_ops, data)))
479 goto out; 481 goto out;
480 task->tk_calldata = data;
481 482
482 /* Mask signals on GSS_AUTH upcalls */ 483 /* Mask signals on GSS_AUTH upcalls */
483 rpc_task_sigmask(task, &oldset); 484 rpc_task_sigmask(task, &oldset);
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 */
560void rpc_exit_task(struct rpc_task *task) 560void 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 */
750void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, rpc_action callback, int flags) 750void 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
797static void 800static void rpc_free_task(struct rpc_task *task)
798rpc_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 */
809struct rpc_task * 811struct rpc_task *rpc_new_task(struct rpc_clnt *clnt, int flags, const struct rpc_call_ops *tk_ops, void *calldata)
810rpc_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
839void rpc_release_task(struct rpc_task *task) 837void 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 */
886static inline struct rpc_task *rpc_find_parent(struct rpc_task *child) 888static 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
899static void rpc_child_exit(struct rpc_task *child) 900static 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
912static 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
926fail: 929fail:
@@ -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}