Commit db60df88 authored by Nicholas Bellinger's avatar Nicholas Bellinger

target: Fail on non zero scsi_status in compare_and_write_callback

This patch addresses a bug for backends such as IBLOCK that perform
asynchronous completion via transport_complete_cmd(), that will call
target_complete_failure_work() -> transport_generic_request_failure(),
upon exception status and invoke cmd->transport_complete_callback()
-> compare_and_write_callback() incorrectly during the failure case.

It adds a check for a non zero se_cmd->scsi_status within the first
invocation of compare_and_write_callback(), and will jump to out plus
up se_device->caw_sem before exiting the callback.
Reported-by: default avatarThomas Glanzmann <thomas@glanzmann.de>
Tested-by: default avatarThomas Glanzmann <thomas@glanzmann.de>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent d8855c15
...@@ -372,7 +372,7 @@ static sense_reason_t compare_and_write_callback(struct se_cmd *cmd) ...@@ -372,7 +372,7 @@ static sense_reason_t compare_and_write_callback(struct se_cmd *cmd)
{ {
struct se_device *dev = cmd->se_dev; struct se_device *dev = cmd->se_dev;
struct scatterlist *write_sg = NULL, *sg; struct scatterlist *write_sg = NULL, *sg;
unsigned char *buf, *addr; unsigned char *buf = NULL, *addr;
struct sg_mapping_iter m; struct sg_mapping_iter m;
unsigned int offset = 0, len; unsigned int offset = 0, len;
unsigned int nlbas = cmd->t_task_nolb; unsigned int nlbas = cmd->t_task_nolb;
...@@ -387,6 +387,15 @@ static sense_reason_t compare_and_write_callback(struct se_cmd *cmd) ...@@ -387,6 +387,15 @@ static sense_reason_t compare_and_write_callback(struct se_cmd *cmd)
*/ */
if (!cmd->t_data_sg || !cmd->t_bidi_data_sg) if (!cmd->t_data_sg || !cmd->t_bidi_data_sg)
return TCM_NO_SENSE; return TCM_NO_SENSE;
/*
* Immediately exit + release dev->caw_sem if command has already
* been failed with a non-zero SCSI status.
*/
if (cmd->scsi_status) {
pr_err("compare_and_write_callback: non zero scsi_status:"
" 0x%02x\n", cmd->scsi_status);
goto out;
}
buf = kzalloc(cmd->data_length, GFP_KERNEL); buf = kzalloc(cmd->data_length, GFP_KERNEL);
if (!buf) { if (!buf) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment