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

Commit 76736db3 authored by Sagi Grimberg's avatar Sagi Grimberg Committed by Nicholas Bellinger
Browse files

target: Report bad sector in sense data for DIF errors



SPC-4 states that data-integrity errors shall also report
the failed sector in CHECK_CONDITION response sense data
information field.

Signed-off-by: default avatarSagi Grimberg <sagig@mellanox.com>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent 676687c6
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1131,6 +1131,7 @@ sbc_dif_verify_write(struct se_cmd *cmd, sector_t start, unsigned int sectors,
			if (rc) {
				kunmap_atomic(paddr);
				kunmap_atomic(daddr);
				cmd->bad_sector = sector;
				return rc;
			}

@@ -1191,6 +1192,7 @@ sbc_dif_verify_read(struct se_cmd *cmd, sector_t start, unsigned int sectors,
			if (rc) {
				kunmap_atomic(paddr);
				kunmap_atomic(daddr);
				cmd->bad_sector = sector;
				return rc;
			}

+16 −0
Original line number Diff line number Diff line
@@ -2493,6 +2493,19 @@ static int transport_get_sense_codes(
	return 0;
}

static
void transport_err_sector_info(unsigned char *buffer, sector_t bad_sector)
{
	/* Place failed LBA in sense data information descriptor 0. */
	buffer[SPC_ADD_SENSE_LEN_OFFSET] = 0xc;
	buffer[SPC_DESC_TYPE_OFFSET] = 0; /* Information */
	buffer[SPC_ADDITIONAL_DESC_LEN_OFFSET] = 0xa;
	buffer[SPC_VALIDITY_OFFSET] = 0x80;

	/* Descriptor Information: failing sector */
	put_unaligned_be64(bad_sector, &buffer[12]);
}

int
transport_send_check_condition_and_sense(struct se_cmd *cmd,
		sense_reason_t reason, int from_transport)
@@ -2695,6 +2708,7 @@ transport_send_check_condition_and_sense(struct se_cmd *cmd,
		/* LOGICAL BLOCK GUARD CHECK FAILED */
		buffer[SPC_ASC_KEY_OFFSET] = 0x10;
		buffer[SPC_ASCQ_KEY_OFFSET] = 0x01;
		transport_err_sector_info(buffer, cmd->bad_sector);
		break;
	case TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED:
		/* CURRENT ERROR */
@@ -2705,6 +2719,7 @@ transport_send_check_condition_and_sense(struct se_cmd *cmd,
		/* LOGICAL BLOCK APPLICATION TAG CHECK FAILED */
		buffer[SPC_ASC_KEY_OFFSET] = 0x10;
		buffer[SPC_ASCQ_KEY_OFFSET] = 0x02;
		transport_err_sector_info(buffer, cmd->bad_sector);
		break;
	case TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED:
		/* CURRENT ERROR */
@@ -2715,6 +2730,7 @@ transport_send_check_condition_and_sense(struct se_cmd *cmd,
		/* LOGICAL BLOCK REFERENCE TAG CHECK FAILED */
		buffer[SPC_ASC_KEY_OFFSET] = 0x10;
		buffer[SPC_ASCQ_KEY_OFFSET] = 0x03;
		transport_err_sector_info(buffer, cmd->bad_sector);
		break;
	case TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE:
	default:
+4 −1
Original line number Diff line number Diff line
@@ -37,6 +37,9 @@
/* Used by transport_send_check_condition_and_sense() */
#define SPC_SENSE_KEY_OFFSET			2
#define SPC_ADD_SENSE_LEN_OFFSET		7
#define SPC_DESC_TYPE_OFFSET			8
#define SPC_ADDITIONAL_DESC_LEN_OFFSET		9
#define SPC_VALIDITY_OFFSET			10
#define SPC_ASC_KEY_OFFSET			12
#define SPC_ASCQ_KEY_OFFSET			13
#define TRANSPORT_IQN_LEN			224
@@ -560,7 +563,7 @@ struct se_cmd {
	unsigned int		t_prot_nents;
	enum target_prot_ho	prot_handover;
	sense_reason_t		pi_err;
	u32			block_num;
	sector_t		bad_sector;
};

struct se_ua {