Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 735703ca authored by Nicholas Bellinger's avatar Nicholas Bellinger
Browse files

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: default avatarRoland Dreier <roland@purestorage.com>
Cc: Roland Dreier <roland@purestorage.com>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent 1edcdb49
Loading
Loading
Loading
Loading
+10 −8
Original line number Original line Diff line number Diff line
@@ -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
	 * Locate se_lun pointer and attach it to struct se_cmd
	 */
	 */
	if (transport_lookup_cmd_lun(se_cmd, unpacked_lun) < 0)
	if (transport_lookup_cmd_lun(se_cmd, unpacked_lun) < 0) {
		goto out_check_cond;
		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
	 * Sanitize CDBs via transport_generic_cmd_sequencer() and
	 * allocate the necessary tasks to complete the received CDB+data
	 * allocate the necessary tasks to complete the received CDB+data
	 */
	 */
	rc = transport_generic_allocate_tasks(se_cmd, cdb);
	rc = transport_generic_allocate_tasks(se_cmd, cdb);
	if (rc != 0)
	if (rc != 0) {
		goto out_check_cond;
		transport_generic_request_failure(se_cmd);
		return;
	}
	/*
	/*
	 * Dispatch se_cmd descriptor to se_lun->lun_se_dev backend
	 * Dispatch se_cmd descriptor to se_lun->lun_se_dev backend
	 * for immediate execution of READs, otherwise wait for
	 * 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);
	transport_handle_cdb_direct(se_cmd);
	return;
	return;

out_check_cond:
	transport_send_check_condition_and_sense(se_cmd,
				se_cmd->scsi_sense_reason, 0);
}
}
EXPORT_SYMBOL(target_submit_cmd);
EXPORT_SYMBOL(target_submit_cmd);