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.c221
1 files changed, 146 insertions, 75 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 154034b675bd..fa5549079d79 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -226,7 +226,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru
226 goto out_no_principal; 226 goto out_no_principal;
227 } 227 }
228 228
229 kref_init(&clnt->cl_kref); 229 atomic_set(&clnt->cl_count, 1);
230 230
231 err = rpc_setup_pipedir(clnt, program->pipe_dir_name); 231 err = rpc_setup_pipedir(clnt, program->pipe_dir_name);
232 if (err < 0) 232 if (err < 0)
@@ -390,14 +390,14 @@ rpc_clone_client(struct rpc_clnt *clnt)
390 if (new->cl_principal == NULL) 390 if (new->cl_principal == NULL)
391 goto out_no_principal; 391 goto out_no_principal;
392 } 392 }
393 kref_init(&new->cl_kref); 393 atomic_set(&new->cl_count, 1);
394 err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name); 394 err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name);
395 if (err != 0) 395 if (err != 0)
396 goto out_no_path; 396 goto out_no_path;
397 if (new->cl_auth) 397 if (new->cl_auth)
398 atomic_inc(&new->cl_auth->au_count); 398 atomic_inc(&new->cl_auth->au_count);
399 xprt_get(clnt->cl_xprt); 399 xprt_get(clnt->cl_xprt);
400 kref_get(&clnt->cl_kref); 400 atomic_inc(&clnt->cl_count);
401 rpc_register_client(new); 401 rpc_register_client(new);
402 rpciod_up(); 402 rpciod_up();
403 return new; 403 return new;
@@ -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 */
@@ -436,10 +465,8 @@ EXPORT_SYMBOL_GPL(rpc_shutdown_client);
436 * Free an RPC client 465 * Free an RPC client
437 */ 466 */
438static void 467static void
439rpc_free_client(struct kref *kref) 468rpc_free_client(struct rpc_clnt *clnt)
440{ 469{
441 struct rpc_clnt *clnt = container_of(kref, struct rpc_clnt, cl_kref);
442
443 dprintk("RPC: destroying %s client for %s\n", 470 dprintk("RPC: destroying %s client for %s\n",
444 clnt->cl_protname, clnt->cl_server); 471 clnt->cl_protname, clnt->cl_server);
445 if (!IS_ERR(clnt->cl_path.dentry)) { 472 if (!IS_ERR(clnt->cl_path.dentry)) {
@@ -466,12 +493,10 @@ out_free:
466 * Free an RPC client 493 * Free an RPC client
467 */ 494 */
468static void 495static void
469rpc_free_auth(struct kref *kref) 496rpc_free_auth(struct rpc_clnt *clnt)
470{ 497{
471 struct rpc_clnt *clnt = container_of(kref, struct rpc_clnt, cl_kref);
472
473 if (clnt->cl_auth == NULL) { 498 if (clnt->cl_auth == NULL) {
474 rpc_free_client(kref); 499 rpc_free_client(clnt);
475 return; 500 return;
476 } 501 }
477 502
@@ -480,10 +505,11 @@ rpc_free_auth(struct kref *kref)
480 * release remaining GSS contexts. This mechanism ensures 505 * release remaining GSS contexts. This mechanism ensures
481 * that it can do so safely. 506 * that it can do so safely.
482 */ 507 */
483 kref_init(kref); 508 atomic_inc(&clnt->cl_count);
484 rpcauth_release(clnt->cl_auth); 509 rpcauth_release(clnt->cl_auth);
485 clnt->cl_auth = NULL; 510 clnt->cl_auth = NULL;
486 kref_put(kref, rpc_free_client); 511 if (atomic_dec_and_test(&clnt->cl_count))
512 rpc_free_client(clnt);
487} 513}
488 514
489/* 515/*
@@ -496,7 +522,8 @@ rpc_release_client(struct rpc_clnt *clnt)
496 522
497 if (list_empty(&clnt->cl_tasks)) 523 if (list_empty(&clnt->cl_tasks))
498 wake_up(&destroy_wait); 524 wake_up(&destroy_wait);
499 kref_put(&clnt->cl_kref, rpc_free_auth); 525 if (atomic_dec_and_test(&clnt->cl_count))
526 rpc_free_auth(clnt);
500} 527}
501 528
502/** 529/**
@@ -538,6 +565,49 @@ out:
538} 565}
539EXPORT_SYMBOL_GPL(rpc_bind_new_program); 566EXPORT_SYMBOL_GPL(rpc_bind_new_program);
540 567
568void rpc_task_release_client(struct rpc_task *task)
569{
570 struct rpc_clnt *clnt = task->tk_client;
571
572 if (clnt != NULL) {
573 /* Remove from client task list */
574 spin_lock(&clnt->cl_lock);
575 list_del(&task->tk_task);
576 spin_unlock(&clnt->cl_lock);
577 task->tk_client = NULL;
578
579 rpc_release_client(clnt);
580 }
581}
582
583static
584void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt)
585{
586 if (clnt != NULL) {
587 rpc_task_release_client(task);
588 task->tk_client = clnt;
589 atomic_inc(&clnt->cl_count);
590 if (clnt->cl_softrtry)
591 task->tk_flags |= RPC_TASK_SOFT;
592 /* Add to the client's list of all tasks */
593 spin_lock(&clnt->cl_lock);
594 list_add_tail(&task->tk_task, &clnt->cl_tasks);
595 spin_unlock(&clnt->cl_lock);
596 }
597}
598
599static void
600rpc_task_set_rpc_message(struct rpc_task *task, const struct rpc_message *msg)
601{
602 if (msg != NULL) {
603 task->tk_msg.rpc_proc = msg->rpc_proc;
604 task->tk_msg.rpc_argp = msg->rpc_argp;
605 task->tk_msg.rpc_resp = msg->rpc_resp;
606 if (msg->rpc_cred != NULL)
607 task->tk_msg.rpc_cred = get_rpccred(msg->rpc_cred);
608 }
609}
610
541/* 611/*
542 * Default callback for async RPC calls 612 * Default callback for async RPC calls
543 */ 613 */
@@ -556,26 +626,28 @@ static const struct rpc_call_ops rpc_default_ops = {
556 */ 626 */
557struct rpc_task *rpc_run_task(const struct rpc_task_setup *task_setup_data) 627struct rpc_task *rpc_run_task(const struct rpc_task_setup *task_setup_data)
558{ 628{
559 struct rpc_task *task, *ret; 629 struct rpc_task *task;
560 630
561 task = rpc_new_task(task_setup_data); 631 task = rpc_new_task(task_setup_data);
562 if (task == NULL) { 632 if (IS_ERR(task))
563 rpc_release_calldata(task_setup_data->callback_ops,
564 task_setup_data->callback_data);
565 ret = ERR_PTR(-ENOMEM);
566 goto out; 633 goto out;
567 } 634
635 rpc_task_set_client(task, task_setup_data->rpc_client);
636 rpc_task_set_rpc_message(task, task_setup_data->rpc_message);
568 637
569 if (task->tk_status != 0) { 638 if (task->tk_status != 0) {
570 ret = ERR_PTR(task->tk_status); 639 int ret = task->tk_status;
571 rpc_put_task(task); 640 rpc_put_task(task);
572 goto out; 641 return ERR_PTR(ret);
573 } 642 }
643
644 if (task->tk_action == NULL)
645 rpc_call_start(task);
646
574 atomic_inc(&task->tk_count); 647 atomic_inc(&task->tk_count);
575 rpc_execute(task); 648 rpc_execute(task);
576 ret = task;
577out: 649out:
578 return ret; 650 return task;
579} 651}
580EXPORT_SYMBOL_GPL(rpc_run_task); 652EXPORT_SYMBOL_GPL(rpc_run_task);
581 653
@@ -657,7 +729,7 @@ struct rpc_task *rpc_run_bc_task(struct rpc_rqst *req,
657 * Create an rpc_task to send the data 729 * Create an rpc_task to send the data
658 */ 730 */
659 task = rpc_new_task(&task_setup_data); 731 task = rpc_new_task(&task_setup_data);
660 if (!task) { 732 if (IS_ERR(task)) {
661 xprt_free_bc_request(req); 733 xprt_free_bc_request(req);
662 goto out; 734 goto out;
663 } 735 }
@@ -766,12 +838,13 @@ EXPORT_SYMBOL_GPL(rpc_force_rebind);
766 * Restart an (async) RPC call from the call_prepare state. 838 * Restart an (async) RPC call from the call_prepare state.
767 * Usually called from within the exit handler. 839 * Usually called from within the exit handler.
768 */ 840 */
769void 841int
770rpc_restart_call_prepare(struct rpc_task *task) 842rpc_restart_call_prepare(struct rpc_task *task)
771{ 843{
772 if (RPC_ASSASSINATED(task)) 844 if (RPC_ASSASSINATED(task))
773 return; 845 return 0;
774 task->tk_action = rpc_prepare_task; 846 task->tk_action = rpc_prepare_task;
847 return 1;
775} 848}
776EXPORT_SYMBOL_GPL(rpc_restart_call_prepare); 849EXPORT_SYMBOL_GPL(rpc_restart_call_prepare);
777 850
@@ -779,13 +852,13 @@ EXPORT_SYMBOL_GPL(rpc_restart_call_prepare);
779 * Restart an (async) RPC call. Usually called from within the 852 * Restart an (async) RPC call. Usually called from within the
780 * exit handler. 853 * exit handler.
781 */ 854 */
782void 855int
783rpc_restart_call(struct rpc_task *task) 856rpc_restart_call(struct rpc_task *task)
784{ 857{
785 if (RPC_ASSASSINATED(task)) 858 if (RPC_ASSASSINATED(task))
786 return; 859 return 0;
787
788 task->tk_action = call_start; 860 task->tk_action = call_start;
861 return 1;
789} 862}
790EXPORT_SYMBOL_GPL(rpc_restart_call); 863EXPORT_SYMBOL_GPL(rpc_restart_call);
791 864
@@ -834,11 +907,6 @@ call_reserve(struct rpc_task *task)
834{ 907{
835 dprint_status(task); 908 dprint_status(task);
836 909
837 if (!rpcauth_uptodatecred(task)) {
838 task->tk_action = call_refresh;
839 return;
840 }
841
842 task->tk_status = 0; 910 task->tk_status = 0;
843 task->tk_action = call_reserveresult; 911 task->tk_action = call_reserveresult;
844 xprt_reserve(task); 912 xprt_reserve(task);
@@ -861,7 +929,7 @@ call_reserveresult(struct rpc_task *task)
861 task->tk_status = 0; 929 task->tk_status = 0;
862 if (status >= 0) { 930 if (status >= 0) {
863 if (task->tk_rqstp) { 931 if (task->tk_rqstp) {
864 task->tk_action = call_allocate; 932 task->tk_action = call_refresh;
865 return; 933 return;
866 } 934 }
867 935
@@ -896,13 +964,54 @@ call_reserveresult(struct rpc_task *task)
896} 964}
897 965
898/* 966/*
899 * 2. Allocate the buffer. For details, see sched.c:rpc_malloc. 967 * 2. Bind and/or refresh the credentials
968 */
969static void
970call_refresh(struct rpc_task *task)
971{
972 dprint_status(task);
973
974 task->tk_action = call_refreshresult;
975 task->tk_status = 0;
976 task->tk_client->cl_stats->rpcauthrefresh++;
977 rpcauth_refreshcred(task);
978}
979
980/*
981 * 2a. Process the results of a credential refresh
982 */
983static void
984call_refreshresult(struct rpc_task *task)
985{
986 int status = task->tk_status;
987
988 dprint_status(task);
989
990 task->tk_status = 0;
991 task->tk_action = call_allocate;
992 if (status >= 0 && rpcauth_uptodatecred(task))
993 return;
994 switch (status) {
995 case -EACCES:
996 rpc_exit(task, -EACCES);
997 return;
998 case -ENOMEM:
999 rpc_exit(task, -ENOMEM);
1000 return;
1001 case -ETIMEDOUT:
1002 rpc_delay(task, 3*HZ);
1003 }
1004 task->tk_action = call_refresh;
1005}
1006
1007/*
1008 * 2b. Allocate the buffer. For details, see sched.c:rpc_malloc.
900 * (Note: buffer memory is freed in xprt_release). 1009 * (Note: buffer memory is freed in xprt_release).
901 */ 1010 */
902static void 1011static void
903call_allocate(struct rpc_task *task) 1012call_allocate(struct rpc_task *task)
904{ 1013{
905 unsigned int slack = task->tk_msg.rpc_cred->cr_auth->au_cslack; 1014 unsigned int slack = task->tk_rqstp->rq_cred->cr_auth->au_cslack;
906 struct rpc_rqst *req = task->tk_rqstp; 1015 struct rpc_rqst *req = task->tk_rqstp;
907 struct rpc_xprt *xprt = task->tk_xprt; 1016 struct rpc_xprt *xprt = task->tk_xprt;
908 struct rpc_procinfo *proc = task->tk_msg.rpc_proc; 1017 struct rpc_procinfo *proc = task->tk_msg.rpc_proc;
@@ -1482,44 +1591,6 @@ out_retry:
1482 } 1591 }
1483} 1592}
1484 1593
1485/*
1486 * 8. Refresh the credentials if rejected by the server
1487 */
1488static void
1489call_refresh(struct rpc_task *task)
1490{
1491 dprint_status(task);
1492
1493 task->tk_action = call_refreshresult;
1494 task->tk_status = 0;
1495 task->tk_client->cl_stats->rpcauthrefresh++;
1496 rpcauth_refreshcred(task);
1497}
1498
1499/*
1500 * 8a. Process the results of a credential refresh
1501 */
1502static void
1503call_refreshresult(struct rpc_task *task)
1504{
1505 int status = task->tk_status;
1506
1507 dprint_status(task);
1508
1509 task->tk_status = 0;
1510 task->tk_action = call_reserve;
1511 if (status >= 0 && rpcauth_uptodatecred(task))
1512 return;
1513 if (status == -EACCES) {
1514 rpc_exit(task, -EACCES);
1515 return;
1516 }
1517 task->tk_action = call_refresh;
1518 if (status != -ETIMEDOUT)
1519 rpc_delay(task, 3*HZ);
1520 return;
1521}
1522
1523static __be32 * 1594static __be32 *
1524rpc_encode_header(struct rpc_task *task) 1595rpc_encode_header(struct rpc_task *task)
1525{ 1596{