SUNRPC: Move remaining RPC client related task initialisation into clnt.c
Now that rpc_run_task() is the sole entry point for RPC calls, we can move the remaining rpc_client-related initialisation of struct rpc_task from sched.c into clnt.c. Also move rpc_killall_tasks() into the same file, since that too is relative to the rpc_clnt. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
parent
d9b6cd9460
commit
58f9612c6e
|
@ -131,6 +131,7 @@ struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *,
|
||||||
struct rpc_clnt *rpc_clone_client(struct rpc_clnt *);
|
struct rpc_clnt *rpc_clone_client(struct rpc_clnt *);
|
||||||
void rpc_shutdown_client(struct rpc_clnt *);
|
void rpc_shutdown_client(struct rpc_clnt *);
|
||||||
void rpc_release_client(struct rpc_clnt *);
|
void rpc_release_client(struct rpc_clnt *);
|
||||||
|
void rpc_task_release_client(struct rpc_task *);
|
||||||
|
|
||||||
int rpcb_register(u32, u32, int, unsigned short);
|
int rpcb_register(u32, u32, int, unsigned short);
|
||||||
int rpcb_v4_register(const u32 program, const u32 version,
|
int rpcb_v4_register(const u32 program, const u32 version,
|
||||||
|
|
|
@ -413,6 +413,35 @@ out_no_clnt:
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rpc_clone_client);
|
EXPORT_SYMBOL_GPL(rpc_clone_client);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Kill all tasks for the given client.
|
||||||
|
* XXX: kill their descendants as well?
|
||||||
|
*/
|
||||||
|
void rpc_killall_tasks(struct rpc_clnt *clnt)
|
||||||
|
{
|
||||||
|
struct rpc_task *rovr;
|
||||||
|
|
||||||
|
|
||||||
|
if (list_empty(&clnt->cl_tasks))
|
||||||
|
return;
|
||||||
|
dprintk("RPC: killing all tasks for client %p\n", clnt);
|
||||||
|
/*
|
||||||
|
* Spin lock all_tasks to prevent changes...
|
||||||
|
*/
|
||||||
|
spin_lock(&clnt->cl_lock);
|
||||||
|
list_for_each_entry(rovr, &clnt->cl_tasks, tk_task) {
|
||||||
|
if (!RPC_IS_ACTIVATED(rovr))
|
||||||
|
continue;
|
||||||
|
if (!(rovr->tk_flags & RPC_TASK_KILLED)) {
|
||||||
|
rovr->tk_flags |= RPC_TASK_KILLED;
|
||||||
|
rpc_exit(rovr, -EIO);
|
||||||
|
rpc_wake_up_queued_task(rovr->tk_waitqueue, rovr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spin_unlock(&clnt->cl_lock);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(rpc_killall_tasks);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Properly shut down an RPC client, terminating all outstanding
|
* Properly shut down an RPC client, terminating all outstanding
|
||||||
* requests.
|
* requests.
|
||||||
|
@ -538,6 +567,49 @@ out:
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rpc_bind_new_program);
|
EXPORT_SYMBOL_GPL(rpc_bind_new_program);
|
||||||
|
|
||||||
|
void rpc_task_release_client(struct rpc_task *task)
|
||||||
|
{
|
||||||
|
struct rpc_clnt *clnt = task->tk_client;
|
||||||
|
|
||||||
|
if (clnt != NULL) {
|
||||||
|
/* Remove from client task list */
|
||||||
|
spin_lock(&clnt->cl_lock);
|
||||||
|
list_del(&task->tk_task);
|
||||||
|
spin_unlock(&clnt->cl_lock);
|
||||||
|
task->tk_client = NULL;
|
||||||
|
|
||||||
|
rpc_release_client(clnt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt)
|
||||||
|
{
|
||||||
|
if (clnt != NULL) {
|
||||||
|
rpc_task_release_client(task);
|
||||||
|
task->tk_client = clnt;
|
||||||
|
kref_get(&clnt->cl_kref);
|
||||||
|
if (clnt->cl_softrtry)
|
||||||
|
task->tk_flags |= RPC_TASK_SOFT;
|
||||||
|
/* Add to the client's list of all tasks */
|
||||||
|
spin_lock(&clnt->cl_lock);
|
||||||
|
list_add_tail(&task->tk_task, &clnt->cl_tasks);
|
||||||
|
spin_unlock(&clnt->cl_lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rpc_task_set_rpc_message(struct rpc_task *task, const struct rpc_message *msg)
|
||||||
|
{
|
||||||
|
if (msg != NULL) {
|
||||||
|
task->tk_msg.rpc_proc = msg->rpc_proc;
|
||||||
|
task->tk_msg.rpc_argp = msg->rpc_argp;
|
||||||
|
task->tk_msg.rpc_resp = msg->rpc_resp;
|
||||||
|
/* Bind the user cred */
|
||||||
|
rpcauth_bindcred(task, msg->rpc_cred, task->tk_flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default callback for async RPC calls
|
* Default callback for async RPC calls
|
||||||
*/
|
*/
|
||||||
|
@ -562,6 +634,18 @@ struct rpc_task *rpc_run_task(const struct rpc_task_setup *task_setup_data)
|
||||||
if (IS_ERR(task))
|
if (IS_ERR(task))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
rpc_task_set_client(task, task_setup_data->rpc_client);
|
||||||
|
rpc_task_set_rpc_message(task, task_setup_data->rpc_message);
|
||||||
|
|
||||||
|
if (task->tk_status != 0) {
|
||||||
|
int ret = task->tk_status;
|
||||||
|
rpc_put_task(task);
|
||||||
|
return ERR_PTR(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (task->tk_action == NULL)
|
||||||
|
rpc_call_start(task);
|
||||||
|
|
||||||
atomic_inc(&task->tk_count);
|
atomic_inc(&task->tk_count);
|
||||||
rpc_execute(task);
|
rpc_execute(task);
|
||||||
out:
|
out:
|
||||||
|
|
|
@ -246,17 +246,8 @@ static inline void rpc_task_set_debuginfo(struct rpc_task *task)
|
||||||
|
|
||||||
static void rpc_set_active(struct rpc_task *task)
|
static void rpc_set_active(struct rpc_task *task)
|
||||||
{
|
{
|
||||||
struct rpc_clnt *clnt;
|
|
||||||
if (test_and_set_bit(RPC_TASK_ACTIVE, &task->tk_runstate) != 0)
|
|
||||||
return;
|
|
||||||
rpc_task_set_debuginfo(task);
|
rpc_task_set_debuginfo(task);
|
||||||
/* Add to global list of all tasks */
|
set_bit(RPC_TASK_ACTIVE, &task->tk_runstate);
|
||||||
clnt = task->tk_client;
|
|
||||||
if (clnt != NULL) {
|
|
||||||
spin_lock(&clnt->cl_lock);
|
|
||||||
list_add_tail(&task->tk_task, &clnt->cl_tasks);
|
|
||||||
spin_unlock(&clnt->cl_lock);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -319,11 +310,6 @@ static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
|
||||||
dprintk("RPC: %5u sleep_on(queue \"%s\" time %lu)\n",
|
dprintk("RPC: %5u sleep_on(queue \"%s\" time %lu)\n",
|
||||||
task->tk_pid, rpc_qname(q), jiffies);
|
task->tk_pid, rpc_qname(q), jiffies);
|
||||||
|
|
||||||
if (!RPC_IS_ASYNC(task) && !RPC_IS_ACTIVATED(task)) {
|
|
||||||
printk(KERN_ERR "RPC: Inactive synchronous task put to sleep!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
__rpc_add_wait_queue(q, task);
|
__rpc_add_wait_queue(q, task);
|
||||||
|
|
||||||
BUG_ON(task->tk_callback != NULL);
|
BUG_ON(task->tk_callback != NULL);
|
||||||
|
@ -334,8 +320,8 @@ static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
|
||||||
void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
|
void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
|
||||||
rpc_action action)
|
rpc_action action)
|
||||||
{
|
{
|
||||||
/* Mark the task as being activated if so needed */
|
/* We shouldn't ever put an inactive task to sleep */
|
||||||
rpc_set_active(task);
|
BUG_ON(!RPC_IS_ACTIVATED(task));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Protect the queue operations.
|
* Protect the queue operations.
|
||||||
|
@ -807,26 +793,9 @@ static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *ta
|
||||||
/* Initialize workqueue for async tasks */
|
/* Initialize workqueue for async tasks */
|
||||||
task->tk_workqueue = task_setup_data->workqueue;
|
task->tk_workqueue = task_setup_data->workqueue;
|
||||||
|
|
||||||
task->tk_client = task_setup_data->rpc_client;
|
|
||||||
if (task->tk_client != NULL) {
|
|
||||||
kref_get(&task->tk_client->cl_kref);
|
|
||||||
if (task->tk_client->cl_softrtry)
|
|
||||||
task->tk_flags |= RPC_TASK_SOFT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (task->tk_ops->rpc_call_prepare != NULL)
|
if (task->tk_ops->rpc_call_prepare != NULL)
|
||||||
task->tk_action = rpc_prepare_task;
|
task->tk_action = rpc_prepare_task;
|
||||||
|
|
||||||
if (task_setup_data->rpc_message != NULL) {
|
|
||||||
task->tk_msg.rpc_proc = task_setup_data->rpc_message->rpc_proc;
|
|
||||||
task->tk_msg.rpc_argp = task_setup_data->rpc_message->rpc_argp;
|
|
||||||
task->tk_msg.rpc_resp = task_setup_data->rpc_message->rpc_resp;
|
|
||||||
/* Bind the user cred */
|
|
||||||
rpcauth_bindcred(task, task_setup_data->rpc_message->rpc_cred, task_setup_data->flags);
|
|
||||||
if (task->tk_action == NULL)
|
|
||||||
rpc_call_start(task);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* starting timestamp */
|
/* starting timestamp */
|
||||||
task->tk_start = ktime_get();
|
task->tk_start = ktime_get();
|
||||||
|
|
||||||
|
@ -896,10 +865,7 @@ void rpc_put_task(struct rpc_task *task)
|
||||||
xprt_release(task);
|
xprt_release(task);
|
||||||
if (task->tk_msg.rpc_cred)
|
if (task->tk_msg.rpc_cred)
|
||||||
rpcauth_unbindcred(task);
|
rpcauth_unbindcred(task);
|
||||||
if (task->tk_client) {
|
rpc_task_release_client(task);
|
||||||
rpc_release_client(task->tk_client);
|
|
||||||
task->tk_client = NULL;
|
|
||||||
}
|
|
||||||
if (task->tk_workqueue != NULL) {
|
if (task->tk_workqueue != NULL) {
|
||||||
INIT_WORK(&task->u.tk_work, rpc_async_release);
|
INIT_WORK(&task->u.tk_work, rpc_async_release);
|
||||||
queue_work(task->tk_workqueue, &task->u.tk_work);
|
queue_work(task->tk_workqueue, &task->u.tk_work);
|
||||||
|
@ -912,13 +878,6 @@ static void rpc_release_task(struct rpc_task *task)
|
||||||
{
|
{
|
||||||
dprintk("RPC: %5u release task\n", task->tk_pid);
|
dprintk("RPC: %5u release task\n", task->tk_pid);
|
||||||
|
|
||||||
if (!list_empty(&task->tk_task)) {
|
|
||||||
struct rpc_clnt *clnt = task->tk_client;
|
|
||||||
/* Remove from client task list */
|
|
||||||
spin_lock(&clnt->cl_lock);
|
|
||||||
list_del(&task->tk_task);
|
|
||||||
spin_unlock(&clnt->cl_lock);
|
|
||||||
}
|
|
||||||
BUG_ON (RPC_IS_QUEUED(task));
|
BUG_ON (RPC_IS_QUEUED(task));
|
||||||
|
|
||||||
/* Wake up anyone who is waiting for task completion */
|
/* Wake up anyone who is waiting for task completion */
|
||||||
|
@ -927,34 +886,6 @@ static void rpc_release_task(struct rpc_task *task)
|
||||||
rpc_put_task(task);
|
rpc_put_task(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Kill all tasks for the given client.
|
|
||||||
* XXX: kill their descendants as well?
|
|
||||||
*/
|
|
||||||
void rpc_killall_tasks(struct rpc_clnt *clnt)
|
|
||||||
{
|
|
||||||
struct rpc_task *rovr;
|
|
||||||
|
|
||||||
|
|
||||||
if (list_empty(&clnt->cl_tasks))
|
|
||||||
return;
|
|
||||||
dprintk("RPC: killing all tasks for client %p\n", clnt);
|
|
||||||
/*
|
|
||||||
* Spin lock all_tasks to prevent changes...
|
|
||||||
*/
|
|
||||||
spin_lock(&clnt->cl_lock);
|
|
||||||
list_for_each_entry(rovr, &clnt->cl_tasks, tk_task) {
|
|
||||||
if (! RPC_IS_ACTIVATED(rovr))
|
|
||||||
continue;
|
|
||||||
if (!(rovr->tk_flags & RPC_TASK_KILLED)) {
|
|
||||||
rovr->tk_flags |= RPC_TASK_KILLED;
|
|
||||||
rpc_exit(rovr, -EIO);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spin_unlock(&clnt->cl_lock);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(rpc_killall_tasks);
|
|
||||||
|
|
||||||
int rpciod_up(void)
|
int rpciod_up(void)
|
||||||
{
|
{
|
||||||
return try_module_get(THIS_MODULE) ? 0 : -EINVAL;
|
return try_module_get(THIS_MODULE) ? 0 : -EINVAL;
|
||||||
|
|
Loading…
Reference in New Issue