diff options
Diffstat (limited to 'net/sunrpc/clnt.c')
-rw-r--r-- | net/sunrpc/clnt.c | 84 |
1 files changed, 84 insertions, 0 deletions
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: |