Commit 6e0f6aa4 authored by Maurizio Lombardi's avatar Maurizio Lombardi Committed by Martin K. Petersen
Browse files

scsi: target: core: Generate correct identifiers for PR OUT transport IDs



Fix target_parse_pr_out_transport_id() to return a string representing
the transport ID in a human-readable format (e.g., naa.xxxxxxxx...)  for
various SCSI protocol types (SAS, FCP, SRP, SBP).

Previously, the function returned a pointer to the raw binary buffer,
which was incorrectly compared against human-readable strings, causing
comparisons to fail.  Now, the function writes a properly formatted
string into a buffer provided by the caller.  The output format depends
on the transport protocol:

* SAS: 64-bit identifier, "naa." prefix.
* FCP: 64-bit identifier, colon separated values.
* SBP: 64-bit identifier, no prefix.
* SRP: 128-bit identifier, "0x" prefix.
* iSCSI: IQN string.

Signed-off-by: default avatarMaurizio Lombardi <mlombard@redhat.com>
Link: https://lore.kernel.org/r/20250714133738.11054-1-mlombard@redhat.com


Reviewed-by: default avatarDmitry Bogdanov <d.bogdanov@yadro.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 220e6083
Loading
Loading
Loading
Loading
+48 −15
Original line number Diff line number Diff line
@@ -257,11 +257,41 @@ static int iscsi_get_pr_transport_id_len(
	return len;
}

static char *iscsi_parse_pr_out_transport_id(
static void sas_parse_pr_out_transport_id(char *buf, char *i_str)
{
	char hex[17] = {};

	bin2hex(hex, buf + 4, 8);
	snprintf(i_str, TRANSPORT_IQN_LEN, "naa.%s", hex);
}

static void srp_parse_pr_out_transport_id(char *buf, char *i_str)
{
	char hex[33] = {};

	bin2hex(hex, buf + 8, 16);
	snprintf(i_str, TRANSPORT_IQN_LEN, "0x%s", hex);
}

static void fcp_parse_pr_out_transport_id(char *buf, char *i_str)
{
	snprintf(i_str, TRANSPORT_IQN_LEN, "%8phC", buf + 8);
}

static void sbp_parse_pr_out_transport_id(char *buf, char *i_str)
{
	char hex[17] = {};

	bin2hex(hex, buf + 8, 8);
	snprintf(i_str, TRANSPORT_IQN_LEN, "%s", hex);
}

static bool iscsi_parse_pr_out_transport_id(
	struct se_portal_group *se_tpg,
	char *buf,
	u32 *out_tid_len,
	char **port_nexus_ptr)
	char **port_nexus_ptr,
	char *i_str)
{
	char *p;
	int i;
@@ -282,7 +312,7 @@ static char *iscsi_parse_pr_out_transport_id(
	if ((format_code != 0x00) && (format_code != 0x40)) {
		pr_err("Illegal format code: 0x%02x for iSCSI"
			" Initiator Transport ID\n", format_code);
		return NULL;
		return false;
	}
	/*
	 * If the caller wants the TransportID Length, we set that value for the
@@ -306,7 +336,7 @@ static char *iscsi_parse_pr_out_transport_id(
			pr_err("Unable to locate \",i,0x\" separator"
				" for Initiator port identifier: %s\n",
				&buf[4]);
			return NULL;
			return false;
		}
		*p = '\0'; /* Terminate iSCSI Name */
		p += 5; /* Skip over ",i,0x" separator */
@@ -339,7 +369,8 @@ static char *iscsi_parse_pr_out_transport_id(
	} else
		*port_nexus_ptr = NULL;

	return &buf[4];
	strscpy(i_str, &buf[4], TRANSPORT_IQN_LEN);
	return true;
}

int target_get_pr_transport_id_len(struct se_node_acl *nacl,
@@ -387,33 +418,35 @@ int target_get_pr_transport_id(struct se_node_acl *nacl,
	}
}

const char *target_parse_pr_out_transport_id(struct se_portal_group *tpg,
		char *buf, u32 *out_tid_len, char **port_nexus_ptr)
bool target_parse_pr_out_transport_id(struct se_portal_group *tpg,
		char *buf, u32 *out_tid_len, char **port_nexus_ptr, char *i_str)
{
	u32 offset;

	switch (tpg->proto_id) {
	case SCSI_PROTOCOL_SAS:
		/*
		 * Assume the FORMAT CODE 00b from spc4r17, 7.5.4.7 TransportID
		 * for initiator ports using SCSI over SAS Serial SCSI Protocol.
		 */
		offset = 4;
		sas_parse_pr_out_transport_id(buf, i_str);
		break;
	case SCSI_PROTOCOL_SBP:
	case SCSI_PROTOCOL_SRP:
		srp_parse_pr_out_transport_id(buf, i_str);
		break;
	case SCSI_PROTOCOL_FCP:
		offset = 8;
		fcp_parse_pr_out_transport_id(buf, i_str);
		break;
	case SCSI_PROTOCOL_SBP:
		sbp_parse_pr_out_transport_id(buf, i_str);
		break;
	case SCSI_PROTOCOL_ISCSI:
		return iscsi_parse_pr_out_transport_id(tpg, buf, out_tid_len,
					port_nexus_ptr);
					port_nexus_ptr, i_str);
	default:
		pr_err("Unknown proto_id: 0x%02x\n", tpg->proto_id);
		return NULL;
		return false;
	}

	*port_nexus_ptr = NULL;
	*out_tid_len = 24;
	return buf + offset;
	return true;
}
+2 −2
Original line number Diff line number Diff line
@@ -103,8 +103,8 @@ int target_get_pr_transport_id_len(struct se_node_acl *nacl,
int	target_get_pr_transport_id(struct se_node_acl *nacl,
		struct t10_pr_registration *pr_reg, int *format_code,
		unsigned char *buf);
const char *target_parse_pr_out_transport_id(struct se_portal_group *tpg,
		char *buf, u32 *out_tid_len, char **port_nexus_ptr);
bool target_parse_pr_out_transport_id(struct se_portal_group *tpg,
		char *buf, u32 *out_tid_len, char **port_nexus_ptr, char *i_str);

/* target_core_hba.c */
struct se_hba *core_alloc_hba(const char *, u32, u32);
+10 −8
Original line number Diff line number Diff line
@@ -1478,11 +1478,12 @@ core_scsi3_decode_spec_i_port(
	LIST_HEAD(tid_dest_list);
	struct pr_transport_id_holder *tidh_new, *tidh, *tidh_tmp;
	unsigned char *buf, *ptr, proto_ident;
	const unsigned char *i_str = NULL;
	unsigned char i_str[TRANSPORT_IQN_LEN];
	char *iport_ptr = NULL, i_buf[PR_REG_ISID_ID_LEN];
	sense_reason_t ret;
	u32 tpdl, tid_len = 0;
	u32 dest_rtpi = 0;
	bool tid_found;

	/*
	 * Allocate a struct pr_transport_id_holder and setup the
@@ -1571,9 +1572,9 @@ core_scsi3_decode_spec_i_port(
			dest_rtpi = tmp_lun->lun_tpg->tpg_rtpi;

			iport_ptr = NULL;
			i_str = target_parse_pr_out_transport_id(tmp_tpg,
					ptr, &tid_len, &iport_ptr);
			if (!i_str)
			tid_found = target_parse_pr_out_transport_id(tmp_tpg,
					ptr, &tid_len, &iport_ptr, i_str);
			if (!tid_found)
				continue;
			/*
			 * Determine if this SCSI device server requires that
@@ -3151,13 +3152,14 @@ core_scsi3_emulate_pro_register_and_move(struct se_cmd *cmd, u64 res_key,
	struct t10_pr_registration *pr_reg, *pr_res_holder, *dest_pr_reg;
	struct t10_reservation *pr_tmpl = &dev->t10_pr;
	unsigned char *buf;
	const unsigned char *initiator_str;
	unsigned char initiator_str[TRANSPORT_IQN_LEN];
	char *iport_ptr = NULL, i_buf[PR_REG_ISID_ID_LEN] = { };
	u32 tid_len, tmp_tid_len;
	int new_reg = 0, type, scope, matching_iname;
	sense_reason_t ret;
	unsigned short rtpi;
	unsigned char proto_ident;
	bool tid_found;

	if (!se_sess || !se_lun) {
		pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n");
@@ -3276,9 +3278,9 @@ core_scsi3_emulate_pro_register_and_move(struct se_cmd *cmd, u64 res_key,
		ret = TCM_INVALID_PARAMETER_LIST;
		goto out;
	}
	initiator_str = target_parse_pr_out_transport_id(dest_se_tpg,
			&buf[24], &tmp_tid_len, &iport_ptr);
	if (!initiator_str) {
	tid_found = target_parse_pr_out_transport_id(dest_se_tpg,
			&buf[24], &tmp_tid_len, &iport_ptr, initiator_str);
	if (!tid_found) {
		pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate"
			" initiator_str from Transport ID\n");
		ret = TCM_INVALID_PARAMETER_LIST;