target: factor some duplicate code for stopping a task
Christoph Hellwig [Mon, 17 Oct 2011 17:56:46 +0000 (13:56 -0400)]
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>

drivers/target/target_core_tmr.c
drivers/target/target_core_transport.c
include/target/target_core_transport.h

index b8a780f..4e963da 100644 (file)
@@ -236,7 +236,6 @@ static void core_tmr_drain_task_list(
                list_del(&task->t_state_list);
                cmd = task->task_se_cmd;
 
-               spin_lock_irqsave(&cmd->t_state_lock, flags);
                pr_debug("LUN_RESET: %s cmd: %p task: %p"
                        " ITT/CmdSN: 0x%08x/0x%08x, i_state: %d, t_state/"
                        "def_t_state: %d/%d cdb: 0x%02x\n",
@@ -256,22 +255,8 @@ static void core_tmr_drain_task_list(
                        atomic_read(&cmd->t_transport_stop),
                        atomic_read(&cmd->t_transport_sent));
 
-               if (task->task_flags & TF_ACTIVE) {
-                       task->task_flags |= TF_REQUEST_STOP;
-                       spin_unlock_irqrestore(
-                               &cmd->t_state_lock, flags);
-
-                       pr_debug("LUN_RESET: Waiting for task: %p to shutdown"
-                               " for dev: %p\n", task, dev);
-                       wait_for_completion(&task->task_stop_comp);
-                       pr_debug("LUN_RESET Completed task: %p shutdown for"
-                               " dev: %p\n", task, dev);
-
-                       spin_lock_irqsave(&cmd->t_state_lock, flags);
-                       atomic_dec(&cmd->t_task_cdbs_left);
-                       task->task_flags &= ~(TF_ACTIVE | TF_REQUEST_STOP);
-               }
-               __transport_stop_task_timer(task, &flags);
+               spin_lock_irqsave(&cmd->t_state_lock, flags);
+               target_stop_task(task, &flags);
 
                if (!atomic_dec_and_test(&cmd->t_task_cdbs_ex_left)) {
                        spin_unlock_irqrestore(&cmd->t_state_lock, flags);
index 4dc492d..6dab819 100644 (file)
@@ -1762,6 +1762,33 @@ void transport_generic_free_cmd_intr(
 }
 EXPORT_SYMBOL(transport_generic_free_cmd_intr);
 
+/*
+ * If the task is active, request it to be stopped and sleep until it
+ * has completed.
+ */
+bool target_stop_task(struct se_task *task, unsigned long *flags)
+{
+       struct se_cmd *cmd = task->task_se_cmd;
+       bool was_active = false;
+
+       if (task->task_flags & TF_ACTIVE) {
+               task->task_flags |= TF_REQUEST_STOP;
+               spin_unlock_irqrestore(&cmd->t_state_lock, *flags);
+
+               pr_debug("Task %p waiting to complete\n", task);
+               wait_for_completion(&task->task_stop_comp);
+               pr_debug("Task %p stopped successfully\n", task);
+
+               spin_lock_irqsave(&cmd->t_state_lock, *flags);
+               atomic_dec(&cmd->t_task_cdbs_left);
+               task->task_flags &= ~(TF_ACTIVE | TF_REQUEST_STOP);
+               was_active = true;
+       }
+
+       __transport_stop_task_timer(task, flags);
+       return was_active;
+}
+
 static int transport_stop_tasks_for_cmd(struct se_cmd *cmd)
 {
        struct se_task *task, *task_tmp;
@@ -1793,28 +1820,10 @@ static int transport_stop_tasks_for_cmd(struct se_cmd *cmd)
                        continue;
                }
 
-               /*
-                * If the struct se_task is active, sleep until it is returned
-                * from the plugin.
-                */
-               if (task->task_flags & TF_ACTIVE) {
-                       task->task_flags |= TF_REQUEST_STOP;
-                       spin_unlock_irqrestore(&cmd->t_state_lock,
-                                       flags);
-
-                       pr_debug("Task %p waiting to complete\n", task);
-                       wait_for_completion(&task->task_stop_comp);
-                       pr_debug("Task %p stopped successfully\n", task);
-
-                       spin_lock_irqsave(&cmd->t_state_lock, flags);
-                       atomic_dec(&cmd->t_task_cdbs_left);
-                       task->task_flags &= ~(TF_ACTIVE | TF_REQUEST_STOP);
-               } else {
+               if (!target_stop_task(task, &flags)) {
                        pr_debug("Task %p - did nothing\n", task);
                        ret++;
                }
-
-               __transport_stop_task_timer(task, &flags);
        }
        spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 
index 9c7e328..1ba5835 100644 (file)
@@ -171,6 +171,7 @@ extern int transport_generic_handle_data(struct se_cmd *);
 extern void transport_new_cmd_failure(struct se_cmd *);
 extern int transport_generic_handle_tmr(struct se_cmd *);
 extern void transport_generic_free_cmd_intr(struct se_cmd *);
+extern bool target_stop_task(struct se_task *task, unsigned long *flags);
 extern void __transport_stop_task_timer(struct se_task *, unsigned long *);
 extern int transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *, u32,
                                struct scatterlist *, u32);