summary refs log tree commit diff
path: root/drivers/target
diff options
context:
space:
mode:
authorMike Christie <mchristi@redhat.com>2017-05-31 15:52:43 -0500
committerNicholas Bellinger <nab@linux-iscsi.org>2017-07-06 23:11:48 -0700
commit402242c904432207515e3ccb4126ff0dcfba89ca (patch)
tree0939ebb6db376bcd18ffc115b6372b49d74ec5d5 /drivers/target
parent1a444175486026c1a280507f8d82094909acddd2 (diff)
downloadlinux-402242c904432207515e3ccb4126ff0dcfba89ca.tar.gz
target: fix SAM_STAT_BUSY/TASK_SET_FULL handling
If the scsi status was not SAM_STAT_GOOD or there was no transport
sense, we would ignore the scsi status and do a generic not ready
LUN communication failure check condition failure.

The problem is that LUN COMM failure is treated as a hard error
sometimes and will cause apps to get IO errors instead of the OS's SCSI
layer retrying. For example, the tcmu daemon will return SAM_STAT_QUEUE_FULL
when memory runs low and can still make progress but wants the initiator to
reduce the work load. Windows will fail this error directly the app
instead of retrying.

This patch is based on Nick's "target/iblock: Use -EAGAIN/-ENOMEM to
propigate SAM BUSY/TASK_SET_FULL" patch here:

http://comments.gmane.org/gmane.linux.scsi.target.devel/11301

but instead of only setting SAM_STAT_GOOD, SAM_STAT_TASK_SET_FULL
and SAM_STAT_BUSY as success, it sets all non check condition status
as success so they are passed back to the initiator, so passthrough
type backends can return all SCSI status codes. Since only passthrough
uses this, I was not sure if we wanted to add checks for non-passthrough
and specific codes.

Signed-off-by: Mike Christie <mchristi@redhat.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r--drivers/target/target_core_transport.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index b9122a56784e..8735243edf04 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -725,15 +725,23 @@ EXPORT_SYMBOL(transport_copy_sense_to_cmd);
 void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status)
 {
 	struct se_device *dev = cmd->se_dev;
-	int success = scsi_status == GOOD;
+	int success;
 	unsigned long flags;
 
 	cmd->scsi_status = scsi_status;
 
-
 	spin_lock_irqsave(&cmd->t_state_lock, flags);
-	if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE)
+	switch (cmd->scsi_status) {
+	case SAM_STAT_CHECK_CONDITION:
+		if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE)
+			success = 1;
+		else
+			success = 0;
+		break;
+	default:
 		success = 1;
+		break;
+	}
 
 	/*
 	 * Check for case where an explicit ABORT_TASK has been received