aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target
diff options
context:
space:
mode:
authorBart Van Assche <bvanassche@acm.org>2018-11-27 18:52:02 -0500
committerMartin K. Petersen <martin.petersen@oracle.com>2018-12-07 21:22:15 -0500
commitaaa00cc93c1d0fd2693a76ea2ba375ea1ac1a7f3 (patch)
treeda0d9fadd963839970a2526474aa4ce6c473d37e /drivers/target
parentfbbd49235590ca759aada500b5a935e06b7f6708 (diff)
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>
Diffstat (limited to 'drivers/target')
-rw-r--r--drivers/target/iscsi/iscsi_target.c11
-rw-r--r--drivers/target/iscsi/iscsi_target_erl1.c28
-rw-r--r--drivers/target/target_core_tmr.c3
-rw-r--r--drivers/target/target_core_transport.c55
4 files changed, 10 insertions, 87 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index c1d5a173553d..984941e036c8 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -1493,8 +1493,6 @@ __iscsit_check_dataout_hdr(struct iscsi_conn *conn, void *buf,
1493 if (hdr->flags & ISCSI_FLAG_CMD_FINAL) 1493 if (hdr->flags & ISCSI_FLAG_CMD_FINAL)
1494 iscsit_stop_dataout_timer(cmd); 1494 iscsit_stop_dataout_timer(cmd);
1495 1495
1496 transport_check_aborted_status(se_cmd,
1497 (hdr->flags & ISCSI_FLAG_CMD_FINAL));
1498 return iscsit_dump_data_payload(conn, payload_length, 1); 1496 return iscsit_dump_data_payload(conn, payload_length, 1);
1499 } 1497 }
1500 } else { 1498 } else {
@@ -1509,12 +1507,9 @@ __iscsit_check_dataout_hdr(struct iscsi_conn *conn, void *buf,
1509 * TASK_ABORTED status. 1507 * TASK_ABORTED status.
1510 */ 1508 */
1511 if (se_cmd->transport_state & CMD_T_ABORTED) { 1509 if (se_cmd->transport_state & CMD_T_ABORTED) {
1512 if (hdr->flags & ISCSI_FLAG_CMD_FINAL) 1510 if (hdr->flags & ISCSI_FLAG_CMD_FINAL &&
1513 if (--cmd->outstanding_r2ts < 1) { 1511 --cmd->outstanding_r2ts < 1)
1514 iscsit_stop_dataout_timer(cmd); 1512 iscsit_stop_dataout_timer(cmd);
1515 transport_check_aborted_status(
1516 se_cmd, 1);
1517 }
1518 1513
1519 return iscsit_dump_data_payload(conn, payload_length, 1); 1514 return iscsit_dump_data_payload(conn, payload_length, 1);
1520 } 1515 }
diff --git a/drivers/target/iscsi/iscsi_target_erl1.c b/drivers/target/iscsi/iscsi_target_erl1.c
index a211e8154f4c..1b54a9c70851 100644
--- a/drivers/target/iscsi/iscsi_target_erl1.c
+++ b/drivers/target/iscsi/iscsi_target_erl1.c
@@ -943,20 +943,8 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo)
943 return 0; 943 return 0;
944 } 944 }
945 spin_unlock_bh(&cmd->istate_lock); 945 spin_unlock_bh(&cmd->istate_lock);
946 /* 946 if (cmd->se_cmd.transport_state & CMD_T_ABORTED)
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)
955 return 0; 947 return 0;
956 /*
957 * Otherwise send CHECK_CONDITION and sense for
958 * exception
959 */
960 return transport_send_check_condition_and_sense(se_cmd, 948 return transport_send_check_condition_and_sense(se_cmd,
961 cmd->sense_reason, 0); 949 cmd->sense_reason, 0);
962 } 950 }
@@ -974,13 +962,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo)
974 962
975 if (!(cmd->cmd_flags & 963 if (!(cmd->cmd_flags &
976 ICF_NON_IMMEDIATE_UNSOLICITED_DATA)) { 964 ICF_NON_IMMEDIATE_UNSOLICITED_DATA)) {
977 /* 965 if (cmd->se_cmd.transport_state & CMD_T_ABORTED)
978 * Send the delayed TASK_ABORTED status for
979 * WRITEs if no more unsolicitied data is
980 * expected.
981 */
982 if (transport_check_aborted_status(se_cmd, 1)
983 != 0)
984 return 0; 966 return 0;
985 967
986 iscsit_set_dataout_sequence_values(cmd); 968 iscsit_set_dataout_sequence_values(cmd);
@@ -995,11 +977,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo)
995 977
996 if ((cmd->data_direction == DMA_TO_DEVICE) && 978 if ((cmd->data_direction == DMA_TO_DEVICE) &&
997 !(cmd->cmd_flags & ICF_NON_IMMEDIATE_UNSOLICITED_DATA)) { 979 !(cmd->cmd_flags & ICF_NON_IMMEDIATE_UNSOLICITED_DATA)) {
998 /* 980 if (cmd->se_cmd.transport_state & CMD_T_ABORTED)
999 * Send the delayed TASK_ABORTED status for WRITEs if
1000 * no more nsolicitied data is expected.
1001 */
1002 if (transport_check_aborted_status(se_cmd, 1) != 0)
1003 return 0; 981 return 0;
1004 982
1005 iscsit_set_unsoliticed_dataout(cmd); 983 iscsit_set_unsoliticed_dataout(cmd);
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c
index 7359b9d9e82f..71950355074e 100644
--- a/drivers/target/target_core_tmr.c
+++ b/drivers/target/target_core_tmr.c
@@ -165,7 +165,8 @@ void core_tmr_abort_task(
165 printk("ABORT_TASK: Found referenced %s task_tag: %llu\n", 165 printk("ABORT_TASK: Found referenced %s task_tag: %llu\n",
166 se_cmd->se_tfo->fabric_name, ref_tag); 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 continue; 170 continue;
170 171
171 spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); 172 spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 868ee9c28c9a..32457fd7a736 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1805,7 +1805,7 @@ void transport_generic_request_failure(struct se_cmd *cmd,
1805 if (cmd->transport_complete_callback) 1805 if (cmd->transport_complete_callback)
1806 cmd->transport_complete_callback(cmd, false, NULL); 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 return; 1809 return;
1810 1810
1811 switch (sense_reason) { 1811 switch (sense_reason) {
@@ -2012,8 +2012,6 @@ static bool target_handle_task_attr(struct se_cmd *cmd)
2012 return true; 2012 return true;
2013} 2013}
2014 2014
2015static int __transport_check_aborted_status(struct se_cmd *, int);
2016
2017void target_execute_cmd(struct se_cmd *cmd) 2015void target_execute_cmd(struct se_cmd *cmd)
2018{ 2016{
2019 /* 2017 /*
@@ -2023,7 +2021,7 @@ void target_execute_cmd(struct se_cmd *cmd)
2023 * If the received CDB has already been aborted stop processing it here. 2021 * If the received CDB has already been aborted stop processing it here.
2024 */ 2022 */
2025 spin_lock_irq(&cmd->t_state_lock); 2023 spin_lock_irq(&cmd->t_state_lock);
2026 if (__transport_check_aborted_status(cmd, 1)) { 2024 if (cmd->transport_state & CMD_T_ABORTED) {
2027 spin_unlock_irq(&cmd->t_state_lock); 2025 spin_unlock_irq(&cmd->t_state_lock);
2028 return; 2026 return;
2029 } 2027 }
@@ -3237,55 +3235,6 @@ transport_send_check_condition_and_sense(struct se_cmd *cmd,
3237} 3235}
3238EXPORT_SYMBOL(transport_send_check_condition_and_sense); 3236EXPORT_SYMBOL(transport_send_check_condition_and_sense);
3239 3237
3240static int __transport_check_aborted_status(struct se_cmd *cmd, int send_status)
3241 __releases(&cmd->t_state_lock)
3242 __acquires(&cmd->t_state_lock)
3243{
3244 int ret;
3245
3246 assert_spin_locked(&cmd->t_state_lock);
3247 WARN_ON_ONCE(!irqs_disabled());
3248
3249 if (!(cmd->transport_state & CMD_T_ABORTED))
3250 return 0;
3251 /*
3252 * If cmd has been aborted but either no status is to be sent or it has
3253 * already been sent, just return
3254 */
3255 if (!send_status || !(cmd->se_cmd_flags & SCF_SEND_DELAYED_TAS)) {
3256 if (send_status)
3257 cmd->se_cmd_flags |= SCF_SEND_DELAYED_TAS;
3258 return 1;
3259 }
3260
3261 pr_debug("Sending delayed SAM_STAT_TASK_ABORTED status for CDB:"
3262 " 0x%02x ITT: 0x%08llx\n", cmd->t_task_cdb[0], cmd->tag);
3263
3264 cmd->se_cmd_flags &= ~SCF_SEND_DELAYED_TAS;
3265 cmd->scsi_status = SAM_STAT_TASK_ABORTED;
3266 trace_target_cmd_complete(cmd);
3267
3268 spin_unlock_irq(&cmd->t_state_lock);
3269 ret = cmd->se_tfo->queue_status(cmd);
3270 if (ret)
3271 transport_handle_queue_full(cmd, cmd->se_dev, ret, false);
3272 spin_lock_irq(&cmd->t_state_lock);
3273
3274 return 1;
3275}
3276
3277int transport_check_aborted_status(struct se_cmd *cmd, int send_status)
3278{
3279 int ret;
3280
3281 spin_lock_irq(&cmd->t_state_lock);
3282 ret = __transport_check_aborted_status(cmd, send_status);
3283 spin_unlock_irq(&cmd->t_state_lock);
3284
3285 return ret;
3286}
3287EXPORT_SYMBOL(transport_check_aborted_status);
3288
3289void transport_send_task_abort(struct se_cmd *cmd) 3238void transport_send_task_abort(struct se_cmd *cmd)
3290{ 3239{
3291 unsigned long flags; 3240 unsigned long flags;