aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2017-09-29 19:03:24 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2017-11-07 22:43:55 -0500
commitfd2f928b0ddd2fe8876d4f1344df2ace2b715a4d (patch)
tree8f7b0b40eaeb20a6eb2bddb6a1f6a705198f543a
parent1c79df1f349fb6050016cea4ef1dfbc3853a5685 (diff)
target: Fix caw_sem leak in transport_generic_request_failure
With the recent addition of transport_check_aborted_status() within transport_generic_request_failure() to avoid sending a SCSI status exception after CMD_T_ABORTED w/ TAS=1 has occured, it introduced a COMPARE_AND_WRITE early failure regression. Namely when COMPARE_AND_WRITE fails and se_device->caw_sem has been taken by sbc_compare_and_write(), if the new check for transport_check_aborted_status() returns true and exits, cmd->transport_complete_callback() -> compare_and_write_post() is skipped never releasing se_device->caw_sem. This regression was originally introduced by: commit e3b88ee95b4e4bf3e9729a4695d695b9c7c296c8 Author: Bart Van Assche <bart.vanassche@sandisk.com> Date: Tue Feb 14 16:25:45 2017 -0800 target: Fix handling of aborted failed commands To address this bug, move the transport_check_aborted_status() call after transport_complete_task_attr() and cmd->transport_complete_callback(). Cc: Mike Christie <mchristi@redhat.com> Cc: Hannes Reinecke <hare@suse.com> Cc: Bart Van Assche <bart.vanassche@sandisk.com> Cc: stable@vger.kernel.org # 4.11+ Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r--drivers/target/target_core_transport.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index c33d1e95dd17..d02218c71dd6 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1729,9 +1729,6 @@ void transport_generic_request_failure(struct se_cmd *cmd,
1729{ 1729{
1730 int ret = 0, post_ret = 0; 1730 int ret = 0, post_ret = 0;
1731 1731
1732 if (transport_check_aborted_status(cmd, 1))
1733 return;
1734
1735 pr_debug("-----[ Storage Engine Exception; sense_reason %d\n", 1732 pr_debug("-----[ Storage Engine Exception; sense_reason %d\n",
1736 sense_reason); 1733 sense_reason);
1737 target_show_cmd("-----[ ", cmd); 1734 target_show_cmd("-----[ ", cmd);
@@ -1740,6 +1737,7 @@ void transport_generic_request_failure(struct se_cmd *cmd,
1740 * For SAM Task Attribute emulation for failed struct se_cmd 1737 * For SAM Task Attribute emulation for failed struct se_cmd
1741 */ 1738 */
1742 transport_complete_task_attr(cmd); 1739 transport_complete_task_attr(cmd);
1740
1743 /* 1741 /*
1744 * Handle special case for COMPARE_AND_WRITE failure, where the 1742 * Handle special case for COMPARE_AND_WRITE failure, where the
1745 * callback is expected to drop the per device ->caw_sem. 1743 * callback is expected to drop the per device ->caw_sem.
@@ -1748,6 +1746,9 @@ void transport_generic_request_failure(struct se_cmd *cmd,
1748 cmd->transport_complete_callback) 1746 cmd->transport_complete_callback)
1749 cmd->transport_complete_callback(cmd, false, &post_ret); 1747 cmd->transport_complete_callback(cmd, false, &post_ret);
1750 1748
1749 if (transport_check_aborted_status(cmd, 1))
1750 return;
1751
1751 switch (sense_reason) { 1752 switch (sense_reason) {
1752 case TCM_NON_EXISTENT_LUN: 1753 case TCM_NON_EXISTENT_LUN:
1753 case TCM_UNSUPPORTED_SCSI_OPCODE: 1754 case TCM_UNSUPPORTED_SCSI_OPCODE: