aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/clnt.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/clnt.c')
-rw-r--r--net/sunrpc/clnt.c182
1 files changed, 133 insertions, 49 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 756fc324db9e..2388d83b68ff 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 if (msg->rpc_cred != NULL)
609 task->tk_msg.rpc_cred = get_rpccred(msg->rpc_cred);
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:
@@ -756,12 +840,13 @@ EXPORT_SYMBOL_GPL(rpc_force_rebind);
756 * Restart an (async) RPC call from the call_prepare state. 840 * Restart an (async) RPC call from the call_prepare state.
757 * Usually called from within the exit handler. 841 * Usually called from within the exit handler.
758 */ 842 */
759void 843int
760rpc_restart_call_prepare(struct rpc_task *task) 844rpc_restart_call_prepare(struct rpc_task *task)
761{ 845{
762 if (RPC_ASSASSINATED(task)) 846 if (RPC_ASSASSINATED(task))
763 return; 847 return 0;
764 task->tk_action = rpc_prepare_task; 848 task->tk_action = rpc_prepare_task;
849 return 1;
765} 850}
766EXPORT_SYMBOL_GPL(rpc_restart_call_prepare); 851EXPORT_SYMBOL_GPL(rpc_restart_call_prepare);
767 852
@@ -769,13 +854,13 @@ EXPORT_SYMBOL_GPL(rpc_restart_call_prepare);
769 * Restart an (async) RPC call. Usually called from within the 854 * Restart an (async) RPC call. Usually called from within the
770 * exit handler. 855 * exit handler.
771 */ 856 */
772void 857int
773rpc_restart_call(struct rpc_task *task) 858rpc_restart_call(struct rpc_task *task)
774{ 859{
775 if (RPC_ASSASSINATED(task)) 860 if (RPC_ASSASSINATED(task))
776 return; 861 return 0;
777
778 task->tk_action = call_start; 862 task->tk_action = call_start;
863 return 1;
779} 864}
780EXPORT_SYMBOL_GPL(rpc_restart_call); 865EXPORT_SYMBOL_GPL(rpc_restart_call);
781 866
@@ -824,11 +909,6 @@ call_reserve(struct rpc_task *task)
824{ 909{
825 dprint_status(task); 910 dprint_status(task);
826 911
827 if (!rpcauth_uptodatecred(task)) {
828 task->tk_action = call_refresh;
829 return;
830 }
831
832 task->tk_status = 0; 912 task->tk_status = 0;
833 task->tk_action = call_reserveresult; 913 task->tk_action = call_reserveresult;
834 xprt_reserve(task); 914 xprt_reserve(task);
@@ -892,7 +972,7 @@ call_reserveresult(struct rpc_task *task)
892static void 972static void
893call_allocate(struct rpc_task *task) 973call_allocate(struct rpc_task *task)
894{ 974{
895 unsigned int slack = task->tk_msg.rpc_cred->cr_auth->au_cslack; 975 unsigned int slack = task->tk_client->cl_auth->au_cslack;
896 struct rpc_rqst *req = task->tk_rqstp; 976 struct rpc_rqst *req = task->tk_rqstp;
897 struct rpc_xprt *xprt = task->tk_xprt; 977 struct rpc_xprt *xprt = task->tk_xprt;
898 struct rpc_procinfo *proc = task->tk_msg.rpc_proc; 978 struct rpc_procinfo *proc = task->tk_msg.rpc_proc;
@@ -900,7 +980,7 @@ call_allocate(struct rpc_task *task)
900 dprint_status(task); 980 dprint_status(task);
901 981
902 task->tk_status = 0; 982 task->tk_status = 0;
903 task->tk_action = call_bind; 983 task->tk_action = call_refresh;
904 984
905 if (req->rq_buffer) 985 if (req->rq_buffer)
906 return; 986 return;
@@ -937,6 +1017,47 @@ call_allocate(struct rpc_task *task)
937 rpc_exit(task, -ERESTARTSYS); 1017 rpc_exit(task, -ERESTARTSYS);
938} 1018}
939 1019
1020/*
1021 * 2a. Bind and/or refresh the credentials
1022 */
1023static void
1024call_refresh(struct rpc_task *task)
1025{
1026 dprint_status(task);
1027
1028 task->tk_action = call_refreshresult;
1029 task->tk_status = 0;
1030 task->tk_client->cl_stats->rpcauthrefresh++;
1031 rpcauth_refreshcred(task);
1032}
1033
1034/*
1035 * 2b. Process the results of a credential refresh
1036 */
1037static void
1038call_refreshresult(struct rpc_task *task)
1039{
1040 int status = task->tk_status;
1041
1042 dprint_status(task);
1043
1044 task->tk_status = 0;
1045 task->tk_action = call_bind;
1046 if (status >= 0 && rpcauth_uptodatecred(task))
1047 return;
1048 switch (status) {
1049 case -EACCES:
1050 rpc_exit(task, -EACCES);
1051 return;
1052 case -ENOMEM:
1053 rpc_exit(task, -ENOMEM);
1054 return;
1055 case -ETIMEDOUT:
1056 rpc_delay(task, 3*HZ);
1057 }
1058 task->tk_action = call_refresh;
1059}
1060
940static inline int 1061static inline int
941rpc_task_need_encode(struct rpc_task *task) 1062rpc_task_need_encode(struct rpc_task *task)
942{ 1063{
@@ -1472,43 +1593,6 @@ out_retry:
1472 } 1593 }
1473} 1594}
1474 1595
1475/*
1476 * 8. Refresh the credentials if rejected by the server
1477 */
1478static void
1479call_refresh(struct rpc_task *task)
1480{
1481 dprint_status(task);
1482
1483 task->tk_action = call_refreshresult;
1484 task->tk_status = 0;
1485 task->tk_client->cl_stats->rpcauthrefresh++;
1486 rpcauth_refreshcred(task);
1487}
1488
1489/*
1490 * 8a. Process the results of a credential refresh
1491 */
1492static void
1493call_refreshresult(struct rpc_task *task)
1494{
1495 int status = task->tk_status;
1496
1497 dprint_status(task);
1498
1499 task->tk_status = 0;
1500 task->tk_action = call_reserve;
1501 if (status >= 0 && rpcauth_uptodatecred(task))
1502 return;
1503 if (status == -EACCES) {
1504 rpc_exit(task, -EACCES);
1505 return;
1506 }
1507 task->tk_action = call_refresh;
1508 if (status != -ETIMEDOUT)
1509 rpc_delay(task, 3*HZ);
1510}
1511
1512static __be32 * 1596static __be32 *
1513rpc_encode_header(struct rpc_task *task) 1597rpc_encode_header(struct rpc_task *task)
1514{ 1598{