Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: target/core: Fix TAS handling for aborted commands

The TASK ABORTED STATUS (TAS) bit is defined as follows in SAM:
"TASK_ABORTED: this status shall be returned if a command is aborted by a
command or task management function on another I_T nexus and the control
mode page TAS bit is set to one". TAS handling is spread over the target
core and the iSCSI target driver. If a LUN RESET is received, the target
core will send the TASK_ABORTED response for all commands for which such a
response has to be sent. If an ABORT TASK is received, only the iSCSI
target driver will send the TASK_ABORTED response for the commands for
which that response has to be sent. That is a bug since all target drivers
have to honor the TAS bit. Fix this by moving the code that handles TAS
from the iSCSI target driver into the target core. Additionally, if a
command has been aborted, instead of sending the TASK_ABORTED status from
the context that processes the SCSI command send it from the context of the
ABORT TMF. The core_tmr_abort_task() change in this patch causes the
CMD_T_TAS flag to be set if a TASK_ABORTED status has to be sent back to
the initiator that submitted the command. If that flag has been set
transport_cmd_finish_abort() will send the TASK_ABORTED response.

Cc: Nicholas Bellinger <nab@linux-iscsi.org>
Cc: Mike Christie <mchristi@redhat.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: David Disseldorp <ddiss@suse.de>
Cc: Hannes Reinecke <hare@suse.de>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Bart Van Assche and committed by
Martin K. Petersen
aaa00cc9 fbbd4923

+10 -89
+3 -8
drivers/target/iscsi/iscsi_target.c
··· 1493 1493 if (hdr->flags & ISCSI_FLAG_CMD_FINAL) 1494 1494 iscsit_stop_dataout_timer(cmd); 1495 1495 1496 - transport_check_aborted_status(se_cmd, 1497 - (hdr->flags & ISCSI_FLAG_CMD_FINAL)); 1498 1496 return iscsit_dump_data_payload(conn, payload_length, 1); 1499 1497 } 1500 1498 } else { ··· 1507 1509 * TASK_ABORTED status. 1508 1510 */ 1509 1511 if (se_cmd->transport_state & CMD_T_ABORTED) { 1510 - if (hdr->flags & ISCSI_FLAG_CMD_FINAL) 1511 - if (--cmd->outstanding_r2ts < 1) { 1512 - iscsit_stop_dataout_timer(cmd); 1513 - transport_check_aborted_status( 1514 - se_cmd, 1); 1515 - } 1512 + if (hdr->flags & ISCSI_FLAG_CMD_FINAL && 1513 + --cmd->outstanding_r2ts < 1) 1514 + iscsit_stop_dataout_timer(cmd); 1516 1515 1517 1516 return iscsit_dump_data_payload(conn, payload_length, 1); 1518 1517 }
+3 -25
drivers/target/iscsi/iscsi_target_erl1.c
··· 943 943 return 0; 944 944 } 945 945 spin_unlock_bh(&cmd->istate_lock); 946 - /* 947 - * Determine if delayed TASK_ABORTED status for WRITEs 948 - * should be sent now if no unsolicited data out 949 - * payloads are expected, or if the delayed status 950 - * should be sent after unsolicited data out with 951 - * ISCSI_FLAG_CMD_FINAL set in iscsi_handle_data_out() 952 - */ 953 - if (transport_check_aborted_status(se_cmd, 954 - (cmd->unsolicited_data == 0)) != 0) 946 + if (cmd->se_cmd.transport_state & CMD_T_ABORTED) 955 947 return 0; 956 - /* 957 - * Otherwise send CHECK_CONDITION and sense for 958 - * exception 959 - */ 960 948 return transport_send_check_condition_and_sense(se_cmd, 961 949 cmd->sense_reason, 0); 962 950 } ··· 962 974 963 975 if (!(cmd->cmd_flags & 964 976 ICF_NON_IMMEDIATE_UNSOLICITED_DATA)) { 965 - /* 966 - * Send the delayed TASK_ABORTED status for 967 - * WRITEs if no more unsolicitied data is 968 - * expected. 969 - */ 970 - if (transport_check_aborted_status(se_cmd, 1) 971 - != 0) 977 + if (cmd->se_cmd.transport_state & CMD_T_ABORTED) 972 978 return 0; 973 979 974 980 iscsit_set_dataout_sequence_values(cmd); ··· 977 995 978 996 if ((cmd->data_direction == DMA_TO_DEVICE) && 979 997 !(cmd->cmd_flags & ICF_NON_IMMEDIATE_UNSOLICITED_DATA)) { 980 - /* 981 - * Send the delayed TASK_ABORTED status for WRITEs if 982 - * no more nsolicitied data is expected. 983 - */ 984 - if (transport_check_aborted_status(se_cmd, 1) != 0) 998 + if (cmd->se_cmd.transport_state & CMD_T_ABORTED) 985 999 return 0; 986 1000 987 1001 iscsit_set_unsoliticed_dataout(cmd);
+2 -1
drivers/target/target_core_tmr.c
··· 165 165 printk("ABORT_TASK: Found referenced %s task_tag: %llu\n", 166 166 se_cmd->se_tfo->fabric_name, ref_tag); 167 167 168 - if (!__target_check_io_state(se_cmd, se_sess, 0)) 168 + if (!__target_check_io_state(se_cmd, se_sess, 169 + dev->dev_attrib.emulate_tas)) 169 170 continue; 170 171 171 172 spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+2 -53
drivers/target/target_core_transport.c
··· 1805 1805 if (cmd->transport_complete_callback) 1806 1806 cmd->transport_complete_callback(cmd, false, NULL); 1807 1807 1808 - if (transport_check_aborted_status(cmd, 1)) 1808 + if (cmd->transport_state & CMD_T_ABORTED) 1809 1809 return; 1810 1810 1811 1811 switch (sense_reason) { ··· 2012 2012 return true; 2013 2013 } 2014 2014 2015 - static int __transport_check_aborted_status(struct se_cmd *, int); 2016 - 2017 2015 void target_execute_cmd(struct se_cmd *cmd) 2018 2016 { 2019 2017 /* ··· 2021 2023 * If the received CDB has already been aborted stop processing it here. 2022 2024 */ 2023 2025 spin_lock_irq(&cmd->t_state_lock); 2024 - if (__transport_check_aborted_status(cmd, 1)) { 2026 + if (cmd->transport_state & CMD_T_ABORTED) { 2025 2027 spin_unlock_irq(&cmd->t_state_lock); 2026 2028 return; 2027 2029 } ··· 3234 3236 return cmd->se_tfo->queue_status(cmd); 3235 3237 } 3236 3238 EXPORT_SYMBOL(transport_send_check_condition_and_sense); 3237 - 3238 - static int __transport_check_aborted_status(struct se_cmd *cmd, int send_status) 3239 - __releases(&cmd->t_state_lock) 3240 - __acquires(&cmd->t_state_lock) 3241 - { 3242 - int ret; 3243 - 3244 - assert_spin_locked(&cmd->t_state_lock); 3245 - WARN_ON_ONCE(!irqs_disabled()); 3246 - 3247 - if (!(cmd->transport_state & CMD_T_ABORTED)) 3248 - return 0; 3249 - /* 3250 - * If cmd has been aborted but either no status is to be sent or it has 3251 - * already been sent, just return 3252 - */ 3253 - if (!send_status || !(cmd->se_cmd_flags & SCF_SEND_DELAYED_TAS)) { 3254 - if (send_status) 3255 - cmd->se_cmd_flags |= SCF_SEND_DELAYED_TAS; 3256 - return 1; 3257 - } 3258 - 3259 - pr_debug("Sending delayed SAM_STAT_TASK_ABORTED status for CDB:" 3260 - " 0x%02x ITT: 0x%08llx\n", cmd->t_task_cdb[0], cmd->tag); 3261 - 3262 - cmd->se_cmd_flags &= ~SCF_SEND_DELAYED_TAS; 3263 - cmd->scsi_status = SAM_STAT_TASK_ABORTED; 3264 - trace_target_cmd_complete(cmd); 3265 - 3266 - spin_unlock_irq(&cmd->t_state_lock); 3267 - ret = cmd->se_tfo->queue_status(cmd); 3268 - if (ret) 3269 - transport_handle_queue_full(cmd, cmd->se_dev, ret, false); 3270 - spin_lock_irq(&cmd->t_state_lock); 3271 - 3272 - return 1; 3273 - } 3274 - 3275 - int transport_check_aborted_status(struct se_cmd *cmd, int send_status) 3276 - { 3277 - int ret; 3278 - 3279 - spin_lock_irq(&cmd->t_state_lock); 3280 - ret = __transport_check_aborted_status(cmd, send_status); 3281 - spin_unlock_irq(&cmd->t_state_lock); 3282 - 3283 - return ret; 3284 - } 3285 - EXPORT_SYMBOL(transport_check_aborted_status); 3286 3239 3287 3240 void transport_send_task_abort(struct se_cmd *cmd) 3288 3241 {
-1
include/target/target_core_base.h
··· 136 136 SCF_SENT_CHECK_CONDITION = 0x00000800, 137 137 SCF_OVERFLOW_BIT = 0x00001000, 138 138 SCF_UNDERFLOW_BIT = 0x00002000, 139 - SCF_SEND_DELAYED_TAS = 0x00004000, 140 139 SCF_ALUA_NON_OPTIMIZED = 0x00008000, 141 140 SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC = 0x00020000, 142 141 SCF_COMPARE_AND_WRITE = 0x00080000,
-1
include/target/target_core_fabric.h
··· 171 171 int transport_generic_free_cmd(struct se_cmd *, int); 172 172 173 173 bool transport_wait_for_tasks(struct se_cmd *); 174 - int transport_check_aborted_status(struct se_cmd *, int); 175 174 int transport_send_check_condition_and_sense(struct se_cmd *, 176 175 sense_reason_t, int); 177 176 int target_get_sess_cmd(struct se_cmd *, bool);