diff mbox series

[RFC,25/48] target: core: pr: have Transport ID stored

Message ID 20220803162857.27770-26-d.bogdanov@yadro.com
State New
Headers show
Series Target cluster implementation over DLM | expand

Commit Message

Dmitry Bogdanov July 27, 2022, 4:21 p.m. UTC
Store TransportID in pr_reg at its creation.

Signed-off-by: Dmitry Bogdanov <d.bogdanov@yadro.com>
---
 drivers/target/target_core_fabric_lib.c | 130 +++++++++---------------
 drivers/target/target_core_internal.h   |   9 +-
 drivers/target/target_core_pr.c         |  19 ++--
 include/target/target_core_base.h       |   2 +
 4 files changed, 68 insertions(+), 92 deletions(-)
diff mbox series

Patch

diff --git a/drivers/target/target_core_fabric_lib.c b/drivers/target/target_core_fabric_lib.c
index cd1360095036..32c2afbb3033 100644
--- a/drivers/target/target_core_fabric_lib.c
+++ b/drivers/target/target_core_fabric_lib.c
@@ -33,14 +33,14 @@ 
 
 
 static int sas_get_pr_transport_id(
-	struct t10_pr_registration *pr_reg,
-	int *format_code,
+	const char *initiatorname,
 	unsigned char *buf)
 {
 	int ret;
 
+	buf[0] = SCSI_PROTOCOL_SAS;
 	/* Skip over 'naa. prefix */
-	ret = hex2bin(&buf[4], &pr_reg->pr_iport[4], 8);
+	ret = hex2bin(&buf[4], &initiatorname[4], 8);
 	if (ret) {
 		pr_debug("%s: invalid hex string\n", __func__);
 		return ret;
@@ -50,19 +50,19 @@  static int sas_get_pr_transport_id(
 }
 
 static int fc_get_pr_transport_id(
-	struct t10_pr_registration *pr_reg,
-	int *format_code,
+	const char *initiatorname,
 	unsigned char *buf)
 {
-	unsigned char *ptr;
+	const char *ptr;
 	int i, ret;
 	u32 off = 8;
 
+	buf[0] = SCSI_PROTOCOL_FCP;
 	/*
 	 * We convert the ASCII formatted N Port name into a binary
 	 * encoded TransportID.
 	 */
-	ptr = &pr_reg->pr_iport[0];
+	ptr = &initiatorname[0];
 	for (i = 0; i < 23; ) {
 		if (!strncmp(&ptr[i], ":", 1)) {
 			i++;
@@ -82,13 +82,14 @@  static int fc_get_pr_transport_id(
 }
 
 static int sbp_get_pr_transport_id(
-	struct t10_pr_registration *pr_reg,
-	int *format_code,
+	const char *initiatorname,
 	unsigned char *buf)
 {
 	int ret;
 
-	ret = hex2bin(&buf[8], pr_reg->pr_iport, 8);
+	buf[0] = SCSI_PROTOCOL_SBP;
+
+	ret = hex2bin(&buf[8], initiatorname, 8);
 	if (ret) {
 		pr_debug("%s: invalid hex string\n", __func__);
 		return ret;
@@ -98,15 +99,16 @@  static int sbp_get_pr_transport_id(
 }
 
 static int srp_get_pr_transport_id(
-	struct t10_pr_registration *pr_reg,
-	int *format_code,
+	const char *initiatorname,
 	unsigned char *buf)
 {
 	const char *p;
 	unsigned len, count, leading_zero_bytes;
 	int rc;
 
-	p = pr_reg->pr_iport;
+	buf[0] = SCSI_PROTOCOL_SRP;
+
+	p = initiatorname;
 	if (strncasecmp(p, "0x", 2) == 0)
 		p += 2;
 	len = strlen(p);
@@ -126,14 +128,16 @@  static int srp_get_pr_transport_id(
 }
 
 static int iscsi_get_pr_transport_id(
-	struct t10_pr_registration *pr_reg,
-	int *format_code,
+	const char *initiatorname,
+	unsigned char *isid,
 	unsigned char *buf)
 {
 	u32 off = 4, padding = 0;
 	int isid_len;
 	u16 len = 0;
 
+	buf[0] = SCSI_PROTOCOL_ISCSI;
+
 	/*
 	 * Only null terminate the last field.
 	 *
@@ -149,9 +153,9 @@  static int iscsi_get_pr_transport_id(
 	 * length of the iSCSI TransportID or the contents of the ADDITIONAL
 	 * LENGTH field.
 	 */
-	len = sprintf(&buf[off], "%s", pr_reg->pr_iport);
+	len = sprintf(&buf[off], "%s", initiatorname);
 	off += len;
-	if ((*format_code == 1) && (pr_reg->isid_present_at_reg)) {
+	if (isid) {
 		/*
 		 * Set FORMAT CODE 01b for iSCSI Initiator port TransportID
 		 * format.
@@ -185,7 +189,7 @@  static int iscsi_get_pr_transport_id(
 		buf[off++] = 0x78; /* ASCII Character: "x" */
 		len += 5;
 
-		isid_len = sprintf(buf + off, "%s", pr_reg->pr_reg_isid);
+		isid_len = sprintf(buf + off, "%s", isid);
 		off += isid_len;
 		len += isid_len;
 	}
@@ -210,47 +214,6 @@  static int iscsi_get_pr_transport_id(
 	return len;
 }
 
-static int iscsi_get_pr_transport_id_len(
-	struct t10_pr_registration *pr_reg,
-	int *format_code)
-{
-	u32 len = 0, padding = 0;
-
-	len = strlen(pr_reg->pr_iport);
-	/*
-	 * Add extra byte for NULL terminator
-	 */
-	len++;
-	/*
-	 * If there is ISID present with the registration, use format code:
-	 * 01b: iSCSI Initiator port TransportID format
-	 *
-	 * If there is not an active iSCSI session, use format code:
-	 * 00b: iSCSI Initiator device TransportID format
-	 */
-	if (pr_reg->isid_present_at_reg) {
-		len += 5; /* For ",i,0x" ASCII separator */
-		len += strlen(pr_reg->pr_reg_isid);
-		*format_code = 1;
-	} else
-		*format_code = 0;
-	/*
-	 * The ADDITIONAL LENGTH field specifies the number of bytes that follow
-	 * in the TransportID. The additional length shall be at least 20 and
-	 * shall be a multiple of four.
-	 */
-	padding = ((-len) & 3);
-	if (padding != 0)
-		len += padding;
-	/*
-	 * Increment value for total payload + header length for
-	 * full status descriptor
-	 */
-	len += 4;
-
-	return len;
-}
-
 static char *iscsi_parse_pr_out_transport_id(
 	struct se_portal_group *se_tpg,
 	char *buf,
@@ -336,47 +299,54 @@  static char *iscsi_parse_pr_out_transport_id(
 	return &buf[4];
 }
 
-int target_get_pr_transport_id_len(
-		struct t10_pr_registration *pr_reg, int *format_code)
+int target_get_pr_transport_id_len(struct t10_pr_registration *pr_reg)
 {
-	switch (pr_reg->se_tpg->proto_id) {
+	switch (pr_reg->pr_tid[0] & 0xF) {
 	case SCSI_PROTOCOL_FCP:
 	case SCSI_PROTOCOL_SBP:
 	case SCSI_PROTOCOL_SRP:
 	case SCSI_PROTOCOL_SAS:
-		break;
+		return 24;
 	case SCSI_PROTOCOL_ISCSI:
-		return iscsi_get_pr_transport_id_len(pr_reg, format_code);
+		return get_unaligned_be16(&pr_reg->pr_tid[2]) + 4;
 	default:
-		pr_err("Unknown proto_id: 0x%02x\n", pr_reg->se_tpg->proto_id);
+		WARN(1, "Unknown proto_id: %#x\n", pr_reg->pr_tid[0] & 0xF);
 		return -EINVAL;
 	}
-
-	/*
-	 * Most transports use a fixed length 24 byte identifier.
-	 */
-	*format_code = 0;
-	return 24;
 }
 
 int target_get_pr_transport_id(
-		struct t10_pr_registration *pr_reg, int *format_code,
+		struct t10_pr_registration *pr_reg,
 		unsigned char *buf)
 {
-	switch (pr_reg->se_tpg->proto_id) {
+	int len =  target_get_pr_transport_id_len(pr_reg);
+
+	if (len > 0)
+		memcpy(buf, pr_reg->pr_tid, len);
+
+	return  len;
+}
+
+int target_gen_pr_transport_id(
+	struct t10_pr_registration *pr_reg,
+	int proto_id,
+	const char *initiatorname,
+	unsigned char *isid)
+{
+
+	switch (proto_id) {
 	case SCSI_PROTOCOL_SAS:
-		return sas_get_pr_transport_id(pr_reg, format_code, buf);
+		return sas_get_pr_transport_id(initiatorname, pr_reg->pr_tid);
 	case SCSI_PROTOCOL_SBP:
-		return sbp_get_pr_transport_id(pr_reg, format_code, buf);
+		return sbp_get_pr_transport_id(initiatorname, pr_reg->pr_tid);
 	case SCSI_PROTOCOL_SRP:
-		return srp_get_pr_transport_id(pr_reg, format_code, buf);
+		return srp_get_pr_transport_id(initiatorname, pr_reg->pr_tid);
 	case SCSI_PROTOCOL_FCP:
-		return fc_get_pr_transport_id(pr_reg, format_code, buf);
+		return fc_get_pr_transport_id(initiatorname, pr_reg->pr_tid);
 	case SCSI_PROTOCOL_ISCSI:
-		return iscsi_get_pr_transport_id(pr_reg, format_code,
-				buf);
+		return iscsi_get_pr_transport_id(initiatorname, isid, pr_reg->pr_tid);
 	default:
-		pr_err("Unknown proto_id: 0x%02x\n", pr_reg->se_tpg->proto_id);
+		pr_err("Unknown proto_id: 0x%02x\n", proto_id);
 		return -EINVAL;
 	}
 }
diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h
index b32ac78a26b0..95d5add73578 100644
--- a/drivers/target/target_core_internal.h
+++ b/drivers/target/target_core_internal.h
@@ -98,10 +98,13 @@  void	target_setup_backend_cits(struct target_backend *);
 int	target_fabric_setup_cits(struct target_fabric_configfs *);
 
 /* target_core_fabric_lib.c */
-int	target_get_pr_transport_id_len(struct t10_pr_registration *pr_reg,
-				       int *format_code);
+int	target_get_pr_transport_id_len(struct t10_pr_registration *pr_reg);
 int	target_get_pr_transport_id(struct t10_pr_registration *pr_reg,
-				   int *format_code, unsigned char *buf);
+				   unsigned char *buf);
+int target_gen_pr_transport_id(struct t10_pr_registration *pr_reg,
+			       int proto_id,
+			       const char *initiatorname,
+			       unsigned char *isid);
 const char *target_parse_pr_out_transport_id(struct se_portal_group *tpg,
 		char *buf, u32 *out_tid_len, char **port_nexus_ptr);
 
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
index 1f19bfd0fa00..d9e7d177b65a 100644
--- a/drivers/target/target_core_pr.c
+++ b/drivers/target/target_core_pr.c
@@ -716,6 +716,10 @@  static struct t10_pr_registration *__core_scsi3_alloc_registration(
 						    aptpl);
 	if (!pr_reg)
 		return NULL;
+
+	target_gen_pr_transport_id(pr_reg, nacl->se_tpg->proto_id,
+				   nacl->initiatorname, isid);
+
 	/*
 	 * Return pointer to pr_reg for ALL_TG_PT=0
 	 */
@@ -802,6 +806,9 @@  static struct t10_pr_registration *__core_scsi3_alloc_registration(
 				core_scsi3_lunacl_undepend_item(deve_tmp);
 				goto out;
 			}
+			target_gen_pr_transport_id(pr_reg_atp,
+						   nacl_tmp->se_tpg->proto_id,
+						   nacl_tmp->initiatorname, isid);
 
 			list_add_tail(&pr_reg_atp->pr_reg_atp_mem_list,
 				      &pr_reg->pr_reg_atp_list);
@@ -3829,13 +3836,12 @@  static sense_reason_t
 core_scsi3_pri_read_full_status(struct se_cmd *cmd)
 {
 	struct se_device *dev = cmd->se_dev;
-	struct se_portal_group *se_tpg;
 	struct t10_pr_registration *pr_reg, *pr_reg_tmp;
 	struct t10_reservation *pr_tmpl = &dev->t10_pr;
 	unsigned char *buf;
 	u32 add_desc_len = 0, add_len = 0;
 	u32 off = 8; /* off into first Full Status descriptor */
-	int format_code = 0, pr_res_type = 0, pr_res_scope = 0;
+	int pr_res_type = 0, pr_res_scope = 0;
 	int exp_desc_len, desc_len;
 	bool all_reg = false;
 
@@ -3868,7 +3874,6 @@  core_scsi3_pri_read_full_status(struct se_cmd *cmd)
 	list_for_each_entry_safe(pr_reg, pr_reg_tmp,
 			&pr_tmpl->registration_list, pr_reg_list) {
 
-		se_tpg = pr_reg->se_tpg;
 		add_desc_len = 0;
 
 		atomic_inc_mb(&pr_reg->pr_res_holders);
@@ -3877,8 +3882,7 @@  core_scsi3_pri_read_full_status(struct se_cmd *cmd)
 		 * Determine expected length of $FABRIC_MOD specific
 		 * TransportID full status descriptor..
 		 */
-		exp_desc_len = target_get_pr_transport_id_len(pr_reg,
-					&format_code);
+		exp_desc_len = target_get_pr_transport_id_len(pr_reg);
 		if (exp_desc_len < 0 ||
 		    exp_desc_len + add_len > cmd->data_length) {
 			pr_warn("SPC-3 PRIN READ_FULL_STATUS ran"
@@ -3938,13 +3942,10 @@  core_scsi3_pri_read_full_status(struct se_cmd *cmd)
 		} else
 			off += 2; /* Skip over RELATIVE TARGET PORT IDENTIFIER */
 
-		buf[off+4] = se_tpg->proto_id;
-
 		/*
 		 * Now, have the $FABRIC_MOD fill in the transport ID.
 		 */
-		desc_len = target_get_pr_transport_id(pr_reg,
-				&format_code, &buf[off+4]);
+		desc_len = target_get_pr_transport_id(pr_reg, &buf[off+4]);
 
 		spin_lock(&pr_tmpl->registration_lock);
 		atomic_dec_mb(&pr_reg->pr_res_holders);
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 095b96cb3557..64cb943b5d3a 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -347,6 +347,8 @@  struct t10_pr_registration {
 	/* Used during APTPL metadata reading */
 #define PR_APTPL_MAX_IPORT_LEN			256
 	unsigned char pr_iport[PR_APTPL_MAX_IPORT_LEN];
+#define PR_REG_TID_LEN				228
+	char pr_tid[PR_REG_TID_LEN];
 	/* Reservation effects all target ports */
 	int pr_reg_all_tg_pt;
 	/* Activate Persistence across Target Power Loss */