aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2012-01-20 22:02:56 -0500
committerNicholas Bellinger <nab@linux-iscsi.org>2012-02-07 01:47:11 -0500
commit735703cac08f34a197e1c6331ca9adc8a52d6046 (patch)
tree93e3e09572f681f9f3a360832ba4a84a6f99018e
parent1edcdb497ef418122cd4f98e157660cf594b345a (diff)
target: Fix target_submit_cmd() exception handling
This patch fixes a bug in target_submit_cmd() where the failure path for transport_generic_allocate_tasks() made a direct call to transport_send_check_condition_and_sense() and not calling the final target_put_sess_cmd() release callback. For transport_generic_allocate_tasks() failures, use the proper call to transport_generic_request_failure() to handle kref_put() along with potential internal queue full response processing. It also makes transport_lookup_cmd_lun() failures in target_submit_cmd() use transport_send_check_condition_and_sense() and target_put_sess_cmd() directly to avoid se_cmd->se_dev reference in transport_generic_request_failure() handling. Finally it drops the out_check_cond: label and use direct reference for allocate task failures, and per-se_device queue_full handling is currently not supported for transport_lookup_cmd_lun() failure descriptors due to se_device dependency. Reported-by: Roland Dreier <roland@purestorage.com> Cc: Roland Dreier <roland@purestorage.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r--drivers/target/target_core_transport.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index aace7ee141f3..799b5efcd382 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1690,15 +1690,21 @@ void target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
1690 /* 1690 /*
1691 * Locate se_lun pointer and attach it to struct se_cmd 1691 * Locate se_lun pointer and attach it to struct se_cmd
1692 */ 1692 */
1693 if (transport_lookup_cmd_lun(se_cmd, unpacked_lun) < 0) 1693 if (transport_lookup_cmd_lun(se_cmd, unpacked_lun) < 0) {
1694 goto out_check_cond; 1694 transport_send_check_condition_and_sense(se_cmd,
1695 se_cmd->scsi_sense_reason, 0);
1696 target_put_sess_cmd(se_sess, se_cmd);
1697 return;
1698 }
1695 /* 1699 /*
1696 * Sanitize CDBs via transport_generic_cmd_sequencer() and 1700 * Sanitize CDBs via transport_generic_cmd_sequencer() and
1697 * allocate the necessary tasks to complete the received CDB+data 1701 * allocate the necessary tasks to complete the received CDB+data
1698 */ 1702 */
1699 rc = transport_generic_allocate_tasks(se_cmd, cdb); 1703 rc = transport_generic_allocate_tasks(se_cmd, cdb);
1700 if (rc != 0) 1704 if (rc != 0) {
1701 goto out_check_cond; 1705 transport_generic_request_failure(se_cmd);
1706 return;
1707 }
1702 /* 1708 /*
1703 * Dispatch se_cmd descriptor to se_lun->lun_se_dev backend 1709 * Dispatch se_cmd descriptor to se_lun->lun_se_dev backend
1704 * for immediate execution of READs, otherwise wait for 1710 * for immediate execution of READs, otherwise wait for
@@ -1707,10 +1713,6 @@ void target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
1707 */ 1713 */
1708 transport_handle_cdb_direct(se_cmd); 1714 transport_handle_cdb_direct(se_cmd);
1709 return; 1715 return;
1710
1711out_check_cond:
1712 transport_send_check_condition_and_sense(se_cmd,
1713 se_cmd->scsi_sense_reason, 0);
1714} 1716}
1715EXPORT_SYMBOL(target_submit_cmd); 1717EXPORT_SYMBOL(target_submit_cmd);
1716 1718