diff options
author | Alex Leung <amleung21@yahoo.com> | 2014-03-21 22:20:41 -0700 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-04-07 01:48:50 -0700 |
commit | 68259b5aac13a57cba797b9605ed9812158f0e72 (patch) | |
tree | 914de31ac9381cb8a1f591af859ab91adaeee4db /drivers/target/target_core_tmr.c | |
parent | f46d6a8a01d6bbd83a97140f30a72a89b038807b (diff) |
target: Fix Task Aborted Status (TAS) handling
This patch addresses three of long standing issues wrt to Task
Aborted Status (TAS) handling.
The first is the incorrect assumption in core_tmr_handle_tas_abort()
that TASK_ABORTED status is sent for the task referenced by TMR
ABORT_TASK, and sending TASK_ABORTED status for TMR LUN_RESET on
the same nexus the LUN_RESET was received.
The second is to ensure the lun reference count is dropped within
transport_cmd_finish_abort() by calling transport_lun_remove_cmd()
before invoking transport_cmd_check_stop_to_fabric().
The last is to fix the delayed TAS handling to allow outstanding
WRITEs to complete before sending the TASK_ABORTED status. This
includes changing transport_check_aborted_status() to avoid
processing when SCF_SEND_DELAYED_TAS has not be set, and updating
transport_send_task_abort() to drop the SCF_SENT_DELAYED_TAS
check.
Signed-off-by: Alex Leung <amleung21@yahoo.com>
Cc: Alex Leung <amleung21@yahoo.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target/target_core_tmr.c')
-rw-r--r-- | drivers/target/target_core_tmr.c | 18 |
1 files changed, 6 insertions, 12 deletions
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c index 70c638f730a..3f0338fff24 100644 --- a/drivers/target/target_core_tmr.c +++ b/drivers/target/target_core_tmr.c @@ -87,14 +87,17 @@ static void core_tmr_handle_tas_abort( struct se_cmd *cmd, int tas) { + bool remove = true; /* * TASK ABORTED status (TAS) bit support */ if ((tmr_nacl && - (tmr_nacl == cmd->se_sess->se_node_acl)) || tas) + (tmr_nacl != cmd->se_sess->se_node_acl)) && tas) { + remove = false; transport_send_task_abort(cmd); + } - transport_cmd_finish_abort(cmd, 0); + transport_cmd_finish_abort(cmd, remove); } static int target_check_cdb_and_preempt(struct list_head *list, @@ -150,18 +153,9 @@ void core_tmr_abort_task( cancel_work_sync(&se_cmd->work); transport_wait_for_tasks(se_cmd); - /* - * Now send SAM_STAT_TASK_ABORTED status for the referenced - * se_cmd descriptor.. - */ - transport_send_task_abort(se_cmd); - /* - * Also deal with possible extra acknowledge reference.. - */ - if (se_cmd->se_cmd_flags & SCF_ACK_KREF) - target_put_sess_cmd(se_sess, se_cmd); target_put_sess_cmd(se_sess, se_cmd); + transport_cmd_finish_abort(se_cmd, true); printk("ABORT_TASK: Sending TMR_FUNCTION_COMPLETE for" " ref_tag: %d\n", ref_tag); |