summaryrefslogtreecommitdiffstats
path: root/drivers/target/target_core_tmr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/target/target_core_tmr.c')
-rw-r--r--drivers/target/target_core_tmr.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c
index 89c84d472cd7..e4513ef09159 100644
--- a/drivers/target/target_core_tmr.c
+++ b/drivers/target/target_core_tmr.c
@@ -116,14 +116,16 @@ void core_tmr_abort_task(
struct se_tmr_req *tmr,
struct se_session *se_sess)
{
- struct se_cmd *se_cmd;
+ LIST_HEAD(aborted_list);
+ struct se_cmd *se_cmd, *next;
unsigned long flags;
+ bool rc;
u64 ref_tag;
- spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
- list_for_each_entry(se_cmd, &se_sess->sess_cmd_list, se_cmd_list) {
+ spin_lock_irqsave(&dev->execute_task_lock, flags);
+ list_for_each_entry_safe(se_cmd, next, &dev->state_list, state_list) {
- if (dev != se_cmd->se_dev)
+ if (se_sess != se_cmd->se_sess)
continue;
/* skip task management functions, including tmr->task_cmd */
@@ -137,11 +139,16 @@ void core_tmr_abort_task(
printk("ABORT_TASK: Found referenced %s task_tag: %llu\n",
se_cmd->se_tfo->fabric_name, ref_tag);
- if (!__target_check_io_state(se_cmd, se_sess,
- dev->dev_attrib.emulate_tas))
+ spin_lock(&se_sess->sess_cmd_lock);
+ rc = __target_check_io_state(se_cmd, se_sess, 0);
+ spin_unlock(&se_sess->sess_cmd_lock);
+ if (!rc)
continue;
- spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+ list_move_tail(&se_cmd->state_list, &aborted_list);
+ se_cmd->state_active = false;
+
+ spin_unlock_irqrestore(&dev->execute_task_lock, flags);
/*
* Ensure that this ABORT request is visible to the LU RESET
@@ -151,6 +158,11 @@ void core_tmr_abort_task(
WARN_ON_ONCE(transport_lookup_tmr_lun(tmr->task_cmd) <
0);
+ if (dev->transport->tmr_notify)
+ dev->transport->tmr_notify(dev, TMR_ABORT_TASK,
+ &aborted_list);
+
+ list_del_init(&se_cmd->state_list);
target_put_cmd_and_wait(se_cmd);
printk("ABORT_TASK: Sending TMR_FUNCTION_COMPLETE for"
@@ -159,7 +171,10 @@ void core_tmr_abort_task(
atomic_long_inc(&dev->aborts_complete);
return;
}
- spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+ spin_unlock_irqrestore(&dev->execute_task_lock, flags);
+
+ if (dev->transport->tmr_notify)
+ dev->transport->tmr_notify(dev, TMR_ABORT_TASK, &aborted_list);
printk("ABORT_TASK: Sending TMR_TASK_DOES_NOT_EXIST for ref_tag: %lld\n",
tmr->ref_task_tag);
@@ -312,6 +327,11 @@ static void core_tmr_drain_state_list(
}
spin_unlock_irqrestore(&dev->execute_task_lock, flags);
+ if (dev->transport->tmr_notify)
+ dev->transport->tmr_notify(dev, preempt_and_abort_list ?
+ TMR_LUN_RESET_PRO : TMR_LUN_RESET,
+ &drain_task_list);
+
while (!list_empty(&drain_task_list)) {
cmd = list_entry(drain_task_list.next, struct se_cmd, state_list);
list_del_init(&cmd->state_list);