SUNRPC: Move remaining RPC client related task initialisation into clnt.c
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Sat, 31 Jul 2010 18:29:08 +0000 (14:29 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Wed, 4 Aug 2010 12:54:07 +0000 (08:54 -0400)
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>
include/linux/sunrpc/clnt.h
net/sunrpc/clnt.c
net/sunrpc/sched.c

index debe75532199859eceb34c67f1e758568b0e22f3..569dc722a600d55834055cf22474858ef69f5bae 100644 (file)
@@ -131,6 +131,7 @@ struct rpc_clnt     *rpc_bind_new_program(struct rpc_clnt *,
 struct rpc_clnt *rpc_clone_client(struct rpc_clnt *);
 void           rpc_shutdown_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_v4_register(const u32 program, const u32 version,
index 234c40c15f694390b3babaafb4aca1b4bc2aab6a..3647c81fd68984c42e7ee25d26035d4b0e5e0e9c 100644 (file)
@@ -413,6 +413,35 @@ out_no_clnt:
 }
 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
  * requests.
@@ -538,6 +567,49 @@ out:
 }
 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
  */
@@ -562,6 +634,18 @@ struct rpc_task *rpc_run_task(const struct rpc_task_setup *task_setup_data)
        if (IS_ERR(task))
                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);
        rpc_execute(task);
 out:
index 37452762af7025ea510835690807df85e1d44fd1..a42296db2ecd6a0d11517c528d766c43cc056381 100644 (file)
@@ -246,17 +246,8 @@ static inline void rpc_task_set_debuginfo(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);
-       /* Add to global list of all tasks */
-       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);
-       }
+       set_bit(RPC_TASK_ACTIVE, &task->tk_runstate);
 }
 
 /*
@@ -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",
                        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);
 
        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,
                                rpc_action action)
 {
-       /* Mark the task as being activated if so needed */
-       rpc_set_active(task);
+       /* We shouldn't ever put an inactive task to sleep */
+       BUG_ON(!RPC_IS_ACTIVATED(task));
 
        /*
         * 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 */
        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)
                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 */
        task->tk_start = ktime_get();
 
@@ -896,10 +865,7 @@ void rpc_put_task(struct rpc_task *task)
                xprt_release(task);
        if (task->tk_msg.rpc_cred)
                rpcauth_unbindcred(task);
-       if (task->tk_client) {
-               rpc_release_client(task->tk_client);
-               task->tk_client = NULL;
-       }
+       rpc_task_release_client(task);
        if (task->tk_workqueue != NULL) {
                INIT_WORK(&task->u.tk_work, rpc_async_release);
                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);
 
-       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));
 
        /* 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);
 }
 
-/*
- * 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)
 {
        return try_module_get(THIS_MODULE) ? 0 : -EINVAL;