Blob Blame History Raw
From 537090b427719cd53d3aa72d17235034637a9c42 Mon Sep 17 00:00:00 2001
From: David Disseldorp <ddiss@suse.de>
Date: Wed, 29 Jul 2015 04:23:49 -0500
Subject: [PATCH] target: compare and write backend driver sense handling
References: bsc#1177719 bsc#1213026
Patch-mainline: Not yet, SES clustered LIO/RBD

Currently, backend drivers seem to only fail IO with
SAM_STAT_CHECK_CONDITION which gets us
TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE.
For compare and write support we will want to be able to fail with
TCM_MISCOMPARE_VERIFY.
This patch allows back end drivers to propagate COMPARE AND WRITE
miscompare failures via cmd.scsi_asc , avoiding the need for any kABI
changes.

cmd.bad_sector is used to provide the miscompare offset, which gets
placed in the sense Information field via the
scsi_set_sense_information() helper.

Signed-off-by: David Disseldorp <ddiss@suse.de>
Reviewed-by: Luis Henriques <lhenriques@suse.com>
[ddiss: rebase atop 749c226cf56e ("scsi: target: Return COMPARE AND
 WRITE miscompare offsets")]
---
 drivers/target/target_core_transport.c |   14 ++++++++++++++
 1 file changed, 14 insertions(+)

--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1989,6 +1989,19 @@ void transport_generic_request_failure(s
 {
 	int ret = 0, post_ret;
 
+	if (cmd->se_cmd_flags & SCF_COMPARE_AND_WRITE
+	 && sense_reason == TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE
+	 && cmd->scsi_asc == 0x1d) { /* MISCOMPARE DURING VERIFY OPERATION */
+		/*
+		 * workaround for kABI - backends such as target_core_rbd
+		 * can't provide an alternate sense_reason, so propagate
+		 * COMPARE AND WRITE miscompare errors via the cmd->scsi_asc
+		 * field and overwrite sense_reason here to ensure that asc
+		 * and Information fields get filled properly.
+		 */
+		sense_reason = TCM_MISCOMPARE_VERIFY;
+	}
+
 	pr_debug("-----[ Storage Engine Exception; sense_reason %d\n",
 		 sense_reason);
 	target_show_cmd("-----[ ", cmd);
@@ -2029,6 +2042,7 @@ void transport_generic_request_failure(s
 	case TCM_TOO_MANY_SEGMENT_DESCS:
 	case TCM_UNSUPPORTED_SEGMENT_DESC_TYPE_CODE:
 	case TCM_INVALID_FIELD_IN_COMMAND_IU:
+	case TCM_MISCOMPARE_VERIFY:
 		break;
 	case TCM_OUT_OF_RESOURCES:
 		cmd->scsi_status = SAM_STAT_TASK_SET_FULL;