From 735703cac08f34a197e1c6331ca9adc8a52d6046 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Fri, 20 Jan 2012 19:02:56 -0800 Subject: 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 Cc: Roland Dreier Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_transport.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index aace7ee141f..799b5efcd38 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, /* * Locate se_lun pointer and attach it to struct se_cmd */ - if (transport_lookup_cmd_lun(se_cmd, unpacked_lun) < 0) - goto out_check_cond; + if (transport_lookup_cmd_lun(se_cmd, unpacked_lun) < 0) { + transport_send_check_condition_and_sense(se_cmd, + se_cmd->scsi_sense_reason, 0); + target_put_sess_cmd(se_sess, se_cmd); + return; + } /* * Sanitize CDBs via transport_generic_cmd_sequencer() and * allocate the necessary tasks to complete the received CDB+data */ rc = transport_generic_allocate_tasks(se_cmd, cdb); - if (rc != 0) - goto out_check_cond; + if (rc != 0) { + transport_generic_request_failure(se_cmd); + return; + } /* * Dispatch se_cmd descriptor to se_lun->lun_se_dev backend * 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, */ transport_handle_cdb_direct(se_cmd); return; - -out_check_cond: - transport_send_check_condition_and_sense(se_cmd, - se_cmd->scsi_sense_reason, 0); } EXPORT_SYMBOL(target_submit_cmd); -- cgit v1.2.3