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
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>
---
 drivers/target/target_core_transport.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index d729ad11ec1b..09adaac40b6f 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1789,6 +1789,19 @@ void transport_generic_request_failure(struct se_cmd *cmd,
 {
 	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);
@@ -1828,6 +1841,7 @@ void transport_generic_request_failure(struct se_cmd *cmd,
 	case TCM_UNSUPPORTED_TARGET_DESC_TYPE_CODE:
 	case TCM_TOO_MANY_SEGMENT_DESCS:
 	case TCM_UNSUPPORTED_SEGMENT_DESC_TYPE_CODE:
+	case TCM_MISCOMPARE_VERIFY:
 		break;
 	case TCM_OUT_OF_RESOURCES:
 		cmd->scsi_status = SAM_STAT_TASK_SET_FULL;
@@ -3107,6 +3121,7 @@ static const struct sense_info sense_info_table[] = {
 		.key = MISCOMPARE,
 		.asc = 0x1d, /* MISCOMPARE DURING VERIFY OPERATION */
 		.ascq = 0x00,
+		.add_sector_info = true,
 	},
 	[TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED] = {
 		.key = ABORTED_COMMAND,
-- 
2.26.2