All of lore.kernel.org
 help / color / mirror / Atom feed
* RFC PATCH 00/12] target: add sysfs support
@ 2020-04-20 19:14 ` Mike Christie
  0 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel

The following patches made over Linus's current tree allow lio to
export info about structs that the kernel initiates creation of
via events like initiator login where there is no user interaction
like a mkdir. These patches specificially focus on the
I_T_nexus/session but could be used for other objects if we want.

Why sysfs when we have configfs?

I started with configfs and hit bugs like:

commit cc57c07343bd071cdf1915a91a24ab7d40c9b590
Author: Mike Christie <mchristi@redhat.com>
Date:   Sun Jul 15 18:16:17 2018 -0500

    configfs: fix registered group removal

but it turns out that bug was not really a bug and was just how
configfs was meant to work. It seems it was not meant to be used
where the kernel initiates creation of dirs/files as a result of
some internal action. It's more geared to the user initiating
the creation, and my patch just lead to other bugs and was
reverted:

commit f19e4ed1e1edbfa3c9ccb9fed17759b7d6db24c6
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Thu Aug 29 23:13:30 2019 -0400

    configfs_register_group() shouldn't be (and isn't) called in
rmdirable parts

So to export the session info we have debugfs, sysfs, ioctl,
netlink, etc. sysfs just seemed like a decent fit since one of the
primary users is rtslib and it already has lots of file/dir
handling code.

V2:
- rename top level dir to scsi_target
- Fix extra newline
- Copy data that's exported to sysfs so we do not have to worry about
configfs and sysfs refcounts.
- Export session info needed for tracking sessions in userspace and
handling commands like PGRs there (still needs a way to notify userspace
when sessions are added/deleted, but that will be a different set since
the focus is different).

^ permalink raw reply	[flat|nested] 38+ messages in thread

* RFC PATCH 00/12] target: add sysfs support
@ 2020-04-20 19:14 ` Mike Christie
  0 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel

The following patches made over Linus's current tree allow lio to
export info about structs that the kernel initiates creation of
via events like initiator login where there is no user interaction
like a mkdir. These patches specificially focus on the
I_T_nexus/session but could be used for other objects if we want.

Why sysfs when we have configfs?

I started with configfs and hit bugs like:

commit cc57c07343bd071cdf1915a91a24ab7d40c9b590
Author: Mike Christie <mchristi@redhat.com>
Date:   Sun Jul 15 18:16:17 2018 -0500

    configfs: fix registered group removal

but it turns out that bug was not really a bug and was just how
configfs was meant to work. It seems it was not meant to be used
where the kernel initiates creation of dirs/files as a result of
some internal action. It's more geared to the user initiating
the creation, and my patch just lead to other bugs and was
reverted:

commit f19e4ed1e1edbfa3c9ccb9fed17759b7d6db24c6
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Thu Aug 29 23:13:30 2019 -0400

    configfs_register_group() shouldn't be (and isn't) called in
rmdirable parts

So to export the session info we have debugfs, sysfs, ioctl,
netlink, etc. sysfs just seemed like a decent fit since one of the
primary users is rtslib and it already has lots of file/dir
handling code.

V2:
- rename top level dir to scsi_target
- Fix extra newline
- Copy data that's exported to sysfs so we do not have to worry about
configfs and sysfs refcounts.
- Export session info needed for tracking sessions in userspace and
handling commands like PGRs there (still needs a way to notify userspace
when sessions are added/deleted, but that will be a different set since
the focus is different).




^ permalink raw reply	[flat|nested] 38+ messages in thread

* [RFC PATCH 01/12] target: check enforce_pr_isids during registration
  2020-04-20 19:14 ` Mike Christie
@ 2020-04-20 19:14   ` Mike Christie
  -1 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel
  Cc: Mike Christie

Move the check for enforce_pr_isids to the registration code where we
can fail at the time an initiator tries to register a path without an
isid. In its current place in __core_scsi3_locate_pr_reg, it is too
late because it can be registered and be reported in PR in commands and
it is stuck in this state because we cannot unregister it.

I am sending this bug fix patch with the RFC ones, because the bug
intersects with patch 5 "target: drop sess_get_initiator_sid from PR code".
I will break this out and send as a proper bug fix later.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 drivers/target/target_core_pr.c | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
index 5e93169..cd2d32f 100644
--- a/drivers/target/target_core_pr.c
+++ b/drivers/target/target_core_pr.c
@@ -1176,15 +1176,6 @@ static struct t10_pr_registration *__core_scsi3_locate_pr_reg(
 		 * ISID, then we have found a match.
 		 */
 		if (!pr_reg->isid_present_at_reg) {
-			/*
-			 * Determine if this SCSI device server requires that
-			 * SCSI Intiatior TransportID w/ ISIDs is enforced
-			 * for fabric modules (iSCSI) requiring them.
-			 */
-			if (tpg->se_tpg_tfo->sess_get_initiator_sid != NULL) {
-				if (dev->dev_attrib.enforce_pr_isids)
-					continue;
-			}
 			atomic_inc_mb(&pr_reg->pr_res_holders);
 			spin_unlock(&pr_tmpl->registration_lock);
 			return pr_reg;
@@ -1591,10 +1582,25 @@ static void core_scsi3_lunacl_undepend_item(struct se_dev_entry *se_deve)
 				continue;
 			dest_rtpi = tmp_lun->lun_rtpi;
 
+			iport_ptr = NULL;
 			i_str = target_parse_pr_out_transport_id(tmp_tpg,
 					ptr, &tid_len, &iport_ptr);
 			if (!i_str)
 				continue;
+			/*
+			 * Determine if this SCSI device server requires that
+			 * SCSI Intiatior TransportID w/ ISIDs is enforced
+			 * for fabric modules (iSCSI) requiring them.
+			 */
+			if (tpg->se_tpg_tfo->sess_get_initiator_sid &&
+                            dev->dev_attrib.enforce_pr_isids &&
+			    !iport_ptr) {
+				pr_warn("SPC-PR: enforce_pr_isids is set but a isid has not been sent in the SPEC_I_PT data for %s.",
+					i_str);
+				ret = TCM_INVALID_PARAMETER_LIST;
+				spin_unlock(&dev->se_port_lock);
+				goto out_unmap;
+			}
 
 			atomic_inc_mb(&tmp_tpg->tpg_pr_ref_count);
 			spin_unlock(&dev->se_port_lock);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [RFC PATCH 01/12] target: check enforce_pr_isids during registration
@ 2020-04-20 19:14   ` Mike Christie
  0 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel
  Cc: Mike Christie

Move the check for enforce_pr_isids to the registration code where we
can fail at the time an initiator tries to register a path without an
isid. In its current place in __core_scsi3_locate_pr_reg, it is too
late because it can be registered and be reported in PR in commands and
it is stuck in this state because we cannot unregister it.

I am sending this bug fix patch with the RFC ones, because the bug
intersects with patch 5 "target: drop sess_get_initiator_sid from PR code".
I will break this out and send as a proper bug fix later.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 drivers/target/target_core_pr.c | 24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
index 5e93169..cd2d32f 100644
--- a/drivers/target/target_core_pr.c
+++ b/drivers/target/target_core_pr.c
@@ -1176,15 +1176,6 @@ static struct t10_pr_registration *__core_scsi3_locate_pr_reg(
 		 * ISID, then we have found a match.
 		 */
 		if (!pr_reg->isid_present_at_reg) {
-			/*
-			 * Determine if this SCSI device server requires that
-			 * SCSI Intiatior TransportID w/ ISIDs is enforced
-			 * for fabric modules (iSCSI) requiring them.
-			 */
-			if (tpg->se_tpg_tfo->sess_get_initiator_sid != NULL) {
-				if (dev->dev_attrib.enforce_pr_isids)
-					continue;
-			}
 			atomic_inc_mb(&pr_reg->pr_res_holders);
 			spin_unlock(&pr_tmpl->registration_lock);
 			return pr_reg;
@@ -1591,10 +1582,25 @@ static void core_scsi3_lunacl_undepend_item(struct se_dev_entry *se_deve)
 				continue;
 			dest_rtpi = tmp_lun->lun_rtpi;
 
+			iport_ptr = NULL;
 			i_str = target_parse_pr_out_transport_id(tmp_tpg,
 					ptr, &tid_len, &iport_ptr);
 			if (!i_str)
 				continue;
+			/*
+			 * Determine if this SCSI device server requires that
+			 * SCSI Intiatior TransportID w/ ISIDs is enforced
+			 * for fabric modules (iSCSI) requiring them.
+			 */
+			if (tpg->se_tpg_tfo->sess_get_initiator_sid &&
+                            dev->dev_attrib.enforce_pr_isids &&
+			    !iport_ptr) {
+				pr_warn("SPC-PR: enforce_pr_isids is set but a isid has not been sent in the SPEC_I_PT data for %s.",
+					i_str);
+				ret = TCM_INVALID_PARAMETER_LIST;
+				spin_unlock(&dev->se_port_lock);
+				goto out_unmap;
+			}
 
 			atomic_inc_mb(&tmp_tpg->tpg_pr_ref_count);
 			spin_unlock(&dev->se_port_lock);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [RFC PATCH 02/12] target: separate acl name from port ids
  2020-04-20 19:14 ` Mike Christie
@ 2020-04-20 19:14   ` Mike Christie
  -1 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel
  Cc: Mike Christie

To handle features like PGRs in userspace we need the entire iniaitor
port id. For iscsi that is defined as the initiator name plus the
session identifier. The session id is hidden from users, because
its internal to the drivers, so this patch separates the acl name
from the SCSI port ids.

This will then allow other drivers like SRP to use different values
like the port id or src address for the ACL, but then use the port
id for transport ID checks in target_core_fabric.c.

This will also be used to export the initiator info in the session's
sysfs dir in the last patches, so tools like tcmu-runner can rebuild
its session state used when handling PGR commands.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 drivers/infiniband/ulp/srpt/ib_srpt.c    | 13 +++--
 drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c |  9 +++-
 drivers/scsi/qla2xxx/tcm_qla2xxx.c       |  8 ++-
 drivers/target/loopback/tcm_loop.c       | 24 ++++++++-
 drivers/target/sbp/sbp_target.c          |  9 +++-
 drivers/target/target_core_fabric_lib.c  | 87 ++++++++++++++++++++++++++++++++
 drivers/target/target_core_internal.h    |  1 +
 drivers/target/target_core_transport.c   | 22 +++++---
 drivers/target/tcm_fc/tfc_sess.c         | 10 +++-
 drivers/usb/gadget/function/f_tcm.c      | 11 +++-
 drivers/vhost/scsi.c                     | 25 +++++++--
 drivers/xen/xen-scsiback.c               | 28 ++++++++--
 include/target/target_core_base.h        | 24 +++++++++
 include/target/target_core_fabric.h      |  3 +-
 14 files changed, 245 insertions(+), 29 deletions(-)

diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
index 9855274..caeb32e 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -2144,6 +2144,7 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev,
 			    const char *src_addr)
 {
 	struct srpt_port *sport = &sdev->port[port_num - 1];
+	struct t10_transport_id tpid;
 	struct srpt_nexus *nexus;
 	struct srp_login_rsp *rsp = NULL;
 	struct srp_login_rej *rej = NULL;
@@ -2314,13 +2315,17 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev,
 	tag_num = ch->rq_size;
 	tag_size = 1; /* ib_srpt does not use se_sess->sess_cmd_map */
 
+	memset(&tpid, 0, sizeof(tpid));
+	tpid.proto = SCSI_PROTOCOL_SRP;
+	tpid.srp.port_id = i_port_id + 2;
+
 	mutex_lock(&sport->port_guid_id.mutex);
 	list_for_each_entry(stpg, &sport->port_guid_id.tpg_list, entry) {
 		if (!IS_ERR_OR_NULL(ch->sess))
 			break;
 		ch->sess = target_setup_session(&stpg->tpg, tag_num,
 						tag_size, TARGET_PROT_NORMAL,
-						ch->sess_name, ch, NULL);
+						&tpid, ch->sess_name, ch, NULL);
 	}
 	mutex_unlock(&sport->port_guid_id.mutex);
 
@@ -2329,14 +2334,14 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev,
 		if (!IS_ERR_OR_NULL(ch->sess))
 			break;
 		ch->sess = target_setup_session(&stpg->tpg, tag_num,
-					tag_size, TARGET_PROT_NORMAL, i_port_id,
-					ch, NULL);
+					tag_size, TARGET_PROT_NORMAL, &tpid,
+					i_port_id, ch, NULL);
 		if (!IS_ERR_OR_NULL(ch->sess))
 			break;
 		/* Retry without leading "0x" */
 		ch->sess = target_setup_session(&stpg->tpg, tag_num,
 						tag_size, TARGET_PROT_NORMAL,
-						i_port_id + 2, ch, NULL);
+						&tpid, i_port_id + 2, ch, NULL);
 	}
 	mutex_unlock(&sport->port_gid_id.mutex);
 
diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
index d9e94e8..dba9ec0 100644
--- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
+++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
@@ -2208,6 +2208,7 @@ static int ibmvscsis_make_nexus(struct ibmvscsis_tport *tport)
 {
 	char *name = tport->tport_name;
 	struct ibmvscsis_nexus *nexus;
+	struct t10_transport_id tpid;
 	struct scsi_info *vscsi = container_of(tport, struct scsi_info, tport);
 	int rc;
 
@@ -2222,9 +2223,13 @@ static int ibmvscsis_make_nexus(struct ibmvscsis_tport *tport)
 		return -ENOMEM;
 	}
 
+	memset(&tpid, 0, sizeof(tpid));
+	tpid.proto = SCSI_PROTOCOL_SRP;
+	tpid.srp.port_id = name;
+
 	nexus->se_sess = target_setup_session(&tport->se_tpg, 0, 0,
-					      TARGET_PROT_NORMAL, name, nexus,
-					      NULL);
+					      TARGET_PROT_NORMAL, &tpid, name,
+					      nexus, NULL);
 	if (IS_ERR(nexus->se_sess)) {
 		rc = PTR_ERR(nexus->se_sess);
 		goto transport_init_fail;
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index abe7f79..42a4025 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -1428,6 +1428,7 @@ static int tcm_qla2xxx_check_initiator_node_acl(
 {
 	struct qla_hw_data *ha = vha->hw;
 	struct tcm_qla2xxx_lport *lport;
+	struct t10_transport_id tpid;
 	struct tcm_qla2xxx_tpg *tpg;
 	struct se_session *se_sess;
 	unsigned char port_name[36];
@@ -1454,13 +1455,18 @@ static int tcm_qla2xxx_check_initiator_node_acl(
 	 */
 	memset(&port_name, 0, 36);
 	snprintf(port_name, sizeof(port_name), "%8phC", fc_wwpn);
+
+	memset(&tpid, 0, sizeof(tpid));
+	tpid.proto = SCSI_PROTOCOL_FCP;
+	tpid.fcp.port_name = port_name;
+
 	/*
 	 * Locate our struct se_node_acl either from an explict NodeACL created
 	 * via ConfigFS, or via running in TPG demo mode.
 	 */
 	se_sess = target_setup_session(&tpg->se_tpg, num_tags,
 				       sizeof(struct qla_tgt_cmd),
-				       TARGET_PROT_ALL, port_name,
+				       TARGET_PROT_ALL, &tpid, port_name,
 				       qlat_sess, tcm_qla2xxx_session_cb);
 	if (IS_ERR(se_sess))
 		return PTR_ERR(se_sess);
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index 3305b47..7593a53 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -725,10 +725,11 @@ static int tcm_loop_alloc_sess_cb(struct se_portal_group *se_tpg,
 
 static int tcm_loop_make_nexus(
 	struct tcm_loop_tpg *tl_tpg,
-	const char *name)
+	char *name)
 {
 	struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
 	struct tcm_loop_nexus *tl_nexus;
+	struct t10_transport_id tpid;
 	int ret;
 
 	if (tl_tpg->tl_nexus) {
@@ -736,13 +737,32 @@ static int tcm_loop_make_nexus(
 		return -EEXIST;
 	}
 
+	memset(&tpid, 0, sizeof(tpid));
+	tpid.proto = tl_hba->tl_proto_id;
+
+	switch (tpid.proto) {
+	case SCSI_PROTOCOL_SAS:
+		tpid.sas.addr = name;
+		break;
+	case SCSI_PROTOCOL_FCP:
+		tpid.fcp.port_name = name;
+		break;
+	case SCSI_PROTOCOL_ISCSI:
+		/* we only support format=0 */
+		tpid.iscsi.name = name;
+		break;
+	default:
+		return -EINVAL;
+	}
+
 	tl_nexus = kzalloc(sizeof(*tl_nexus), GFP_KERNEL);
 	if (!tl_nexus)
 		return -ENOMEM;
 
 	tl_nexus->se_sess = target_setup_session(&tl_tpg->tl_se_tpg, 0, 0,
 					TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS,
-					name, tl_nexus, tcm_loop_alloc_sess_cb);
+					&tpid, name, tl_nexus,
+					tcm_loop_alloc_sess_cb);
 	if (IS_ERR(tl_nexus->se_sess)) {
 		ret = PTR_ERR(tl_nexus->se_sess);
 		kfree(tl_nexus);
diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c
index e4a9b9f..9a3121d 100644
--- a/drivers/target/sbp/sbp_target.c
+++ b/drivers/target/sbp/sbp_target.c
@@ -181,6 +181,7 @@ static struct sbp_session *sbp_session_create(
 		struct sbp_tpg *tpg,
 		u64 guid)
 {
+	struct t10_transport_id tpid;
 	struct sbp_session *sess;
 	int ret;
 	char guid_str[17];
@@ -196,10 +197,14 @@ static struct sbp_session *sbp_session_create(
 	INIT_DELAYED_WORK(&sess->maint_work, session_maintenance_work);
 	sess->guid = guid;
 
+	memset(&tpid, 0, sizeof(tpid));
+	tpid.proto = SCSI_PROTOCOL_SBP;
+	tpid.sbp.name = guid_str;
+
 	sess->se_sess = target_setup_session(&tpg->se_tpg, 128,
 					     sizeof(struct sbp_target_request),
-					     TARGET_PROT_NORMAL, guid_str,
-					     sess, NULL);
+					     TARGET_PROT_NORMAL, &tpid,
+					     guid_str, sess, NULL);
 	if (IS_ERR(sess->se_sess)) {
 		pr_err("failed to init se_session\n");
 		ret = PTR_ERR(sess->se_sess);
diff --git a/drivers/target/target_core_fabric_lib.c b/drivers/target/target_core_fabric_lib.c
index 6b4b354..39b0e5e 100644
--- a/drivers/target/target_core_fabric_lib.c
+++ b/drivers/target/target_core_fabric_lib.c
@@ -421,3 +421,90 @@ const char *target_parse_pr_out_transport_id(struct se_portal_group *tpg,
 	*out_tid_len = 24;
 	return buf + offset;
 }
+
+struct t10_transport_id *target_cp_transport_id(struct t10_transport_id *src)
+{
+	struct t10_transport_id *dst;
+
+	dst = kzalloc(sizeof(*dst), GFP_KERNEL);
+	if (!dst)
+		return NULL;
+	dst->format = src->format;
+	dst->proto = src->proto;
+
+	switch (src->proto) {
+	case SCSI_PROTOCOL_FCP:
+		dst->fcp.port_name = kstrdup(src->fcp.port_name, GFP_KERNEL);
+		if (!dst->fcp.port_name)
+			goto free_tpid;
+		break;
+	case SCSI_PROTOCOL_SBP:
+		dst->sbp.name = kstrdup(src->sbp.name, GFP_KERNEL);
+		if (!dst->sbp.name)
+			goto free_tpid;
+		break;
+	case SCSI_PROTOCOL_SRP:
+		dst->srp.port_id = kstrdup(src->srp.port_id, GFP_KERNEL);
+		if (!dst->srp.port_id)
+			goto free_tpid;
+		break;
+	case SCSI_PROTOCOL_SAS:
+		dst->sas.addr = kstrdup(src->sas.addr, GFP_KERNEL);
+		if (!dst->sas.addr)
+			goto free_tpid;
+		break;
+	case SCSI_PROTOCOL_ISCSI:
+		dst->iscsi.name = kstrdup(src->iscsi.name, GFP_KERNEL);
+		if (!dst->iscsi.name)
+			goto free_tpid;
+
+		if (src->format) {
+			dst->iscsi.session_id = kstrdup(src->iscsi.session_id,
+							GFP_KERNEL);
+			if (!dst->iscsi.session_id) {
+				kfree(dst->iscsi.name);
+				goto free_tpid;
+			}
+		}
+		break;
+	default:
+		pr_err("Unknown proto_id: 0x%02x\n", src->proto);
+		return NULL;
+	}
+
+	return dst;
+
+free_tpid:
+	kfree(dst);
+	return NULL;
+}
+EXPORT_SYMBOL(target_cp_transport_id);
+
+void target_free_transport_id(struct t10_transport_id *tpid)
+{
+	if (!tpid)
+		return;
+
+	switch (tpid->proto) {
+	case SCSI_PROTOCOL_FCP:
+		kfree(tpid->fcp.port_name);
+		break;
+	case SCSI_PROTOCOL_SBP:
+		kfree(tpid->sbp.name);
+		break;
+	case SCSI_PROTOCOL_SRP:
+		kfree(tpid->srp.port_id);
+		break;
+	case SCSI_PROTOCOL_SAS:
+		kfree(tpid->sas.addr);
+		break;
+	case SCSI_PROTOCOL_ISCSI:
+		kfree(tpid->iscsi.name);
+		kfree(tpid->iscsi.session_id);
+		break;
+	default:
+		pr_err("Unknown proto_id: 0x%02x\n", tpid->proto);
+		return;
+	}
+	kfree(tpid);
+}
diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h
index 8533444..5e016aa 100644
--- a/drivers/target/target_core_internal.h
+++ b/drivers/target/target_core_internal.h
@@ -104,6 +104,7 @@ int	target_get_pr_transport_id(struct se_node_acl *nacl,
 		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);
+void target_free_transport_id(struct t10_transport_id *tpid);
 
 /* target_core_hba.c */
 struct se_hba *core_alloc_hba(const char *, u32, u32);
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 0ae9e60..adf4a84 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -416,12 +416,13 @@ void transport_register_session(
 struct se_session *
 target_setup_session(struct se_portal_group *tpg,
 		     unsigned int tag_num, unsigned int tag_size,
-		     enum target_prot_op prot_op,
+		     enum target_prot_op prot_op, struct t10_transport_id *tpid,
 		     const char *initiatorname, void *private,
 		     int (*callback)(struct se_portal_group *,
 				     struct se_session *, void *))
 {
 	struct se_session *sess;
+	int rc;
 
 	/*
 	 * If the fabric driver is using percpu-ida based pre allocation
@@ -435,6 +436,12 @@ struct se_session *
 	if (IS_ERR(sess))
 		return sess;
 
+	sess->tpid = target_cp_transport_id(tpid);
+	if (!sess->tpid) {
+		rc = -ENOMEM;
+		goto free_sess;
+	}
+
 	sess->se_node_acl = core_tpg_check_initiator_node_acl(tpg,
 					(unsigned char *)initiatorname);
 	if (!sess->se_node_acl) {
@@ -446,15 +453,17 @@ struct se_session *
 	 * required before transport_register_session().
 	 */
 	if (callback != NULL) {
-		int rc = callback(tpg, sess, private);
-		if (rc) {
-			transport_free_session(sess);
-			return ERR_PTR(rc);
-		}
+		rc = callback(tpg, sess, private);
+		if (rc)
+			goto free_sess;
 	}
 
 	transport_register_session(tpg, sess->se_node_acl, sess, private);
 	return sess;
+
+free_sess:
+	transport_free_session(sess);
+	return ERR_PTR(rc);
 }
 EXPORT_SYMBOL(target_setup_session);
 
@@ -579,6 +588,7 @@ void transport_free_session(struct se_session *se_sess)
 		sbitmap_queue_free(&se_sess->sess_tag_pool);
 		kvfree(se_sess->sess_cmd_map);
 	}
+	target_free_transport_id(se_sess->tpid);
 	percpu_ref_exit(&se_sess->cmd_count);
 	kmem_cache_free(se_sess_cache, se_sess);
 }
diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c
index 4fd6a1d..f261756 100644
--- a/drivers/target/tcm_fc/tfc_sess.c
+++ b/drivers/target/tcm_fc/tfc_sess.c
@@ -208,6 +208,7 @@ static struct ft_sess *ft_sess_create(struct ft_tport *tport, u32 port_id,
 				      struct fc_rport_priv *rdata)
 {
 	struct se_portal_group *se_tpg = &tport->tpg->se_tpg;
+	struct t10_transport_id tpid;
 	struct ft_sess *sess;
 	struct hlist_head *head;
 	unsigned char initiatorname[TRANSPORT_IQN_LEN];
@@ -227,10 +228,15 @@ static struct ft_sess *ft_sess_create(struct ft_tport *tport, u32 port_id,
 	sess->tport = tport;
 	sess->port_id = port_id;
 
+	memset(&tpid, 0, sizeof(tpid));
+	tpid.proto = SCSI_PROTOCOL_FCP;
+	tpid.fcp.port_name = &initiatorname[0];
+
 	sess->se_sess = target_setup_session(se_tpg, TCM_FC_DEFAULT_TAGS,
 					     sizeof(struct ft_cmd),
-					     TARGET_PROT_NORMAL, &initiatorname[0],
-					     sess, ft_sess_alloc_cb);
+					     TARGET_PROT_NORMAL, &tpid,
+					     &initiatorname[0], sess,
+					     ft_sess_alloc_cb);
 	if (IS_ERR(sess->se_sess)) {
 		int rc = PTR_ERR(sess->se_sess);
 		kfree(sess);
diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c
index 3650493..e282eb9 100644
--- a/drivers/usb/gadget/function/f_tcm.c
+++ b/drivers/usb/gadget/function/f_tcm.c
@@ -1564,6 +1564,7 @@ static int usbg_alloc_sess_cb(struct se_portal_group *se_tpg,
 static int tcm_usbg_make_nexus(struct usbg_tpg *tpg, char *name)
 {
 	struct tcm_usbg_nexus *tv_nexus;
+	struct t10_transport_id tpid;
 	int ret = 0;
 
 	mutex_lock(&tpg->tpg_mutex);
@@ -1579,11 +1580,17 @@ static int tcm_usbg_make_nexus(struct usbg_tpg *tpg, char *name)
 		goto out_unlock;
 	}
 
+	memset(&tpid, 0, sizeof(tpid));
+	tpid.proto = tpg->se_tpg.proto_id;
+	/* SPC does not assign a proto id for USB-SCSI so we use SAS naming */
+	tpid.sas.addr = name;
+
 	tv_nexus->tvn_se_sess = target_setup_session(&tpg->se_tpg,
 						     USB_G_DEFAULT_SESSION_TAGS,
 						     sizeof(struct usbg_cmd),
-						     TARGET_PROT_NORMAL, name,
-						     tv_nexus, usbg_alloc_sess_cb);
+						     TARGET_PROT_NORMAL, &tpid,
+						     name, tv_nexus,
+						     usbg_alloc_sess_cb);
 	if (IS_ERR(tv_nexus->tvn_se_sess)) {
 #define MAKE_NEXUS_MSG "core_tpg_check_initiator_node_acl() failed for %s\n"
 		pr_debug(MAKE_NEXUS_MSG, name);
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 0b949a1..bc377ee 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -1937,10 +1937,10 @@ static int vhost_scsi_nexus_cb(struct se_portal_group *se_tpg,
 	return -ENOMEM;
 }
 
-static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg,
-				const char *name)
+static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg, char *name)
 {
 	struct vhost_scsi_nexus *tv_nexus;
+	struct t10_transport_id tpid;
 
 	mutex_lock(&tpg->tv_tpg_mutex);
 	if (tpg->tpg_nexus) {
@@ -1949,6 +1949,25 @@ static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg,
 		return -EEXIST;
 	}
 
+	memset(&tpid, 0, sizeof(tpid));
+	tpid.proto = tpg->se_tpg.proto_id;
+
+	switch (tpid.proto) {
+	case SCSI_PROTOCOL_SAS:
+		tpid.sas.addr = name;
+		break;
+	case SCSI_PROTOCOL_FCP:
+		tpid.fcp.port_name = name;
+		break;
+	case SCSI_PROTOCOL_ISCSI:
+		/* we only support format=0 */
+		tpid.iscsi.name = name;
+		break;
+	default:
+		mutex_unlock(&tpg->tv_tpg_mutex);
+		return -EINVAL;
+	}
+
 	tv_nexus = kzalloc(sizeof(*tv_nexus), GFP_KERNEL);
 	if (!tv_nexus) {
 		mutex_unlock(&tpg->tv_tpg_mutex);
@@ -1964,7 +1983,7 @@ static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg,
 					VHOST_SCSI_DEFAULT_TAGS,
 					sizeof(struct vhost_scsi_cmd),
 					TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS,
-					(unsigned char *)name, tv_nexus,
+					&tpid, (unsigned char *)name, tv_nexus,
 					vhost_scsi_nexus_cb);
 	if (IS_ERR(tv_nexus->tvn_se_sess)) {
 		mutex_unlock(&tpg->tv_tpg_mutex);
diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
index ba0942e..0855a77f 100644
--- a/drivers/xen/xen-scsiback.c
+++ b/drivers/xen/xen-scsiback.c
@@ -1507,10 +1507,10 @@ static int scsiback_alloc_sess_cb(struct se_portal_group *se_tpg,
 	return 0;
 }
 
-static int scsiback_make_nexus(struct scsiback_tpg *tpg,
-				const char *name)
+static int scsiback_make_nexus(struct scsiback_tpg *tpg, char *name)
 {
 	struct scsiback_nexus *tv_nexus;
+	struct t10_transport_id tpid;
 	int ret = 0;
 
 	mutex_lock(&tpg->tv_tpg_mutex);
@@ -1520,6 +1520,25 @@ static int scsiback_make_nexus(struct scsiback_tpg *tpg,
 		goto out_unlock;
 	}
 
+	memset(&tpid, 0, sizeof(tpid));
+	tpid.proto = tpg->se_tpg.proto_id;
+
+	switch (tpid.proto) {
+	case SCSI_PROTOCOL_SAS:
+		tpid.sas.addr = name;
+		break;
+	case SCSI_PROTOCOL_FCP:
+		tpid.fcp.port_name = name;
+		break;
+	case SCSI_PROTOCOL_ISCSI:
+		/* we only support format=0 */
+		tpid.iscsi.name = name;
+		break;
+	default:
+		ret =-EINVAL;
+		goto out_unlock;
+	}
+
 	tv_nexus = kzalloc(sizeof(struct scsiback_nexus), GFP_KERNEL);
 	if (!tv_nexus) {
 		ret = -ENOMEM;
@@ -1529,8 +1548,9 @@ static int scsiback_make_nexus(struct scsiback_tpg *tpg,
 	tv_nexus->tvn_se_sess = target_setup_session(&tpg->se_tpg,
 						     VSCSI_DEFAULT_SESSION_TAGS,
 						     sizeof(struct vscsibk_pend),
-						     TARGET_PROT_NORMAL, name,
-						     tv_nexus, scsiback_alloc_sess_cb);
+						     TARGET_PROT_NORMAL, &tpid,
+						     name, tv_nexus,
+						     scsiback_alloc_sess_cb);
 	if (IS_ERR(tv_nexus->tvn_se_sess)) {
 		kfree(tv_nexus);
 		ret = -ENOMEM;
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 1728e88..cd440ea 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -333,6 +333,29 @@ struct t10_wwn {
 	struct list_head t10_vpd_list;
 };
 
+struct t10_transport_id {
+	union {
+		struct {
+			char *port_name;
+		} fcp;
+		struct {
+			char *addr;
+		} sas;
+		struct {
+			char *name;
+		} sbp;
+		struct {
+			char *port_id;
+		} srp;
+		struct {
+			char *name;
+			char *session_id;
+		} iscsi;
+	};
+	u8 format;
+	u8 proto;
+};
+
 struct t10_pr_registration {
 	/* Used for fabrics that contain WWN+ISID */
 #define PR_REG_ISID_LEN				16
@@ -605,6 +628,7 @@ static inline struct se_node_acl *fabric_stat_to_nacl(struct config_item *item)
 struct se_session {
 	unsigned		sess_tearing_down:1;
 	u64			sess_bin_isid;
+	struct t10_transport_id	*tpid;
 	enum target_prot_op	sup_prot_ops;
 	enum target_prot_type	sess_prot_type;
 	struct se_node_acl	*se_node_acl;
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
index 063f133..6b8a6bc 100644
--- a/include/target/target_core_fabric.h
+++ b/include/target/target_core_fabric.h
@@ -125,9 +125,10 @@ struct target_core_fabric_ops {
 int target_depend_item(struct config_item *item);
 void target_undepend_item(struct config_item *item);
 
+struct t10_transport_id *target_cp_transport_id(struct t10_transport_id *);
 struct se_session *target_setup_session(struct se_portal_group *,
 		unsigned int, unsigned int, enum target_prot_op prot_op,
-		const char *, void *,
+		struct t10_transport_id *, const char *, void *,
 		int (*callback)(struct se_portal_group *,
 				struct se_session *, void *));
 void target_remove_session(struct se_session *);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [RFC PATCH 02/12] target: separate acl name from port ids
@ 2020-04-20 19:14   ` Mike Christie
  0 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel
  Cc: Mike Christie

To handle features like PGRs in userspace we need the entire iniaitor
port id. For iscsi that is defined as the initiator name plus the
session identifier. The session id is hidden from users, because
its internal to the drivers, so this patch separates the acl name
from the SCSI port ids.

This will then allow other drivers like SRP to use different values
like the port id or src address for the ACL, but then use the port
id for transport ID checks in target_core_fabric.c.

This will also be used to export the initiator info in the session's
sysfs dir in the last patches, so tools like tcmu-runner can rebuild
its session state used when handling PGR commands.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 drivers/infiniband/ulp/srpt/ib_srpt.c    | 13 +++--
 drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c |  9 +++-
 drivers/scsi/qla2xxx/tcm_qla2xxx.c       |  8 ++-
 drivers/target/loopback/tcm_loop.c       | 24 ++++++++-
 drivers/target/sbp/sbp_target.c          |  9 +++-
 drivers/target/target_core_fabric_lib.c  | 87 ++++++++++++++++++++++++++++++++
 drivers/target/target_core_internal.h    |  1 +
 drivers/target/target_core_transport.c   | 22 +++++---
 drivers/target/tcm_fc/tfc_sess.c         | 10 +++-
 drivers/usb/gadget/function/f_tcm.c      | 11 +++-
 drivers/vhost/scsi.c                     | 25 +++++++--
 drivers/xen/xen-scsiback.c               | 28 ++++++++--
 include/target/target_core_base.h        | 24 +++++++++
 include/target/target_core_fabric.h      |  3 +-
 14 files changed, 245 insertions(+), 29 deletions(-)

diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
index 9855274..caeb32e 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -2144,6 +2144,7 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev,
 			    const char *src_addr)
 {
 	struct srpt_port *sport = &sdev->port[port_num - 1];
+	struct t10_transport_id tpid;
 	struct srpt_nexus *nexus;
 	struct srp_login_rsp *rsp = NULL;
 	struct srp_login_rej *rej = NULL;
@@ -2314,13 +2315,17 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev,
 	tag_num = ch->rq_size;
 	tag_size = 1; /* ib_srpt does not use se_sess->sess_cmd_map */
 
+	memset(&tpid, 0, sizeof(tpid));
+	tpid.proto = SCSI_PROTOCOL_SRP;
+	tpid.srp.port_id = i_port_id + 2;
+
 	mutex_lock(&sport->port_guid_id.mutex);
 	list_for_each_entry(stpg, &sport->port_guid_id.tpg_list, entry) {
 		if (!IS_ERR_OR_NULL(ch->sess))
 			break;
 		ch->sess = target_setup_session(&stpg->tpg, tag_num,
 						tag_size, TARGET_PROT_NORMAL,
-						ch->sess_name, ch, NULL);
+						&tpid, ch->sess_name, ch, NULL);
 	}
 	mutex_unlock(&sport->port_guid_id.mutex);
 
@@ -2329,14 +2334,14 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev,
 		if (!IS_ERR_OR_NULL(ch->sess))
 			break;
 		ch->sess = target_setup_session(&stpg->tpg, tag_num,
-					tag_size, TARGET_PROT_NORMAL, i_port_id,
-					ch, NULL);
+					tag_size, TARGET_PROT_NORMAL, &tpid,
+					i_port_id, ch, NULL);
 		if (!IS_ERR_OR_NULL(ch->sess))
 			break;
 		/* Retry without leading "0x" */
 		ch->sess = target_setup_session(&stpg->tpg, tag_num,
 						tag_size, TARGET_PROT_NORMAL,
-						i_port_id + 2, ch, NULL);
+						&tpid, i_port_id + 2, ch, NULL);
 	}
 	mutex_unlock(&sport->port_gid_id.mutex);
 
diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
index d9e94e8..dba9ec0 100644
--- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
+++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
@@ -2208,6 +2208,7 @@ static int ibmvscsis_make_nexus(struct ibmvscsis_tport *tport)
 {
 	char *name = tport->tport_name;
 	struct ibmvscsis_nexus *nexus;
+	struct t10_transport_id tpid;
 	struct scsi_info *vscsi = container_of(tport, struct scsi_info, tport);
 	int rc;
 
@@ -2222,9 +2223,13 @@ static int ibmvscsis_make_nexus(struct ibmvscsis_tport *tport)
 		return -ENOMEM;
 	}
 
+	memset(&tpid, 0, sizeof(tpid));
+	tpid.proto = SCSI_PROTOCOL_SRP;
+	tpid.srp.port_id = name;
+
 	nexus->se_sess = target_setup_session(&tport->se_tpg, 0, 0,
-					      TARGET_PROT_NORMAL, name, nexus,
-					      NULL);
+					      TARGET_PROT_NORMAL, &tpid, name,
+					      nexus, NULL);
 	if (IS_ERR(nexus->se_sess)) {
 		rc = PTR_ERR(nexus->se_sess);
 		goto transport_init_fail;
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index abe7f79..42a4025 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -1428,6 +1428,7 @@ static int tcm_qla2xxx_check_initiator_node_acl(
 {
 	struct qla_hw_data *ha = vha->hw;
 	struct tcm_qla2xxx_lport *lport;
+	struct t10_transport_id tpid;
 	struct tcm_qla2xxx_tpg *tpg;
 	struct se_session *se_sess;
 	unsigned char port_name[36];
@@ -1454,13 +1455,18 @@ static int tcm_qla2xxx_check_initiator_node_acl(
 	 */
 	memset(&port_name, 0, 36);
 	snprintf(port_name, sizeof(port_name), "%8phC", fc_wwpn);
+
+	memset(&tpid, 0, sizeof(tpid));
+	tpid.proto = SCSI_PROTOCOL_FCP;
+	tpid.fcp.port_name = port_name;
+
 	/*
 	 * Locate our struct se_node_acl either from an explict NodeACL created
 	 * via ConfigFS, or via running in TPG demo mode.
 	 */
 	se_sess = target_setup_session(&tpg->se_tpg, num_tags,
 				       sizeof(struct qla_tgt_cmd),
-				       TARGET_PROT_ALL, port_name,
+				       TARGET_PROT_ALL, &tpid, port_name,
 				       qlat_sess, tcm_qla2xxx_session_cb);
 	if (IS_ERR(se_sess))
 		return PTR_ERR(se_sess);
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index 3305b47..7593a53 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -725,10 +725,11 @@ static int tcm_loop_alloc_sess_cb(struct se_portal_group *se_tpg,
 
 static int tcm_loop_make_nexus(
 	struct tcm_loop_tpg *tl_tpg,
-	const char *name)
+	char *name)
 {
 	struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
 	struct tcm_loop_nexus *tl_nexus;
+	struct t10_transport_id tpid;
 	int ret;
 
 	if (tl_tpg->tl_nexus) {
@@ -736,13 +737,32 @@ static int tcm_loop_make_nexus(
 		return -EEXIST;
 	}
 
+	memset(&tpid, 0, sizeof(tpid));
+	tpid.proto = tl_hba->tl_proto_id;
+
+	switch (tpid.proto) {
+	case SCSI_PROTOCOL_SAS:
+		tpid.sas.addr = name;
+		break;
+	case SCSI_PROTOCOL_FCP:
+		tpid.fcp.port_name = name;
+		break;
+	case SCSI_PROTOCOL_ISCSI:
+		/* we only support format=0 */
+		tpid.iscsi.name = name;
+		break;
+	default:
+		return -EINVAL;
+	}
+
 	tl_nexus = kzalloc(sizeof(*tl_nexus), GFP_KERNEL);
 	if (!tl_nexus)
 		return -ENOMEM;
 
 	tl_nexus->se_sess = target_setup_session(&tl_tpg->tl_se_tpg, 0, 0,
 					TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS,
-					name, tl_nexus, tcm_loop_alloc_sess_cb);
+					&tpid, name, tl_nexus,
+					tcm_loop_alloc_sess_cb);
 	if (IS_ERR(tl_nexus->se_sess)) {
 		ret = PTR_ERR(tl_nexus->se_sess);
 		kfree(tl_nexus);
diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c
index e4a9b9f..9a3121d 100644
--- a/drivers/target/sbp/sbp_target.c
+++ b/drivers/target/sbp/sbp_target.c
@@ -181,6 +181,7 @@ static struct sbp_session *sbp_session_create(
 		struct sbp_tpg *tpg,
 		u64 guid)
 {
+	struct t10_transport_id tpid;
 	struct sbp_session *sess;
 	int ret;
 	char guid_str[17];
@@ -196,10 +197,14 @@ static struct sbp_session *sbp_session_create(
 	INIT_DELAYED_WORK(&sess->maint_work, session_maintenance_work);
 	sess->guid = guid;
 
+	memset(&tpid, 0, sizeof(tpid));
+	tpid.proto = SCSI_PROTOCOL_SBP;
+	tpid.sbp.name = guid_str;
+
 	sess->se_sess = target_setup_session(&tpg->se_tpg, 128,
 					     sizeof(struct sbp_target_request),
-					     TARGET_PROT_NORMAL, guid_str,
-					     sess, NULL);
+					     TARGET_PROT_NORMAL, &tpid,
+					     guid_str, sess, NULL);
 	if (IS_ERR(sess->se_sess)) {
 		pr_err("failed to init se_session\n");
 		ret = PTR_ERR(sess->se_sess);
diff --git a/drivers/target/target_core_fabric_lib.c b/drivers/target/target_core_fabric_lib.c
index 6b4b354..39b0e5e 100644
--- a/drivers/target/target_core_fabric_lib.c
+++ b/drivers/target/target_core_fabric_lib.c
@@ -421,3 +421,90 @@ const char *target_parse_pr_out_transport_id(struct se_portal_group *tpg,
 	*out_tid_len = 24;
 	return buf + offset;
 }
+
+struct t10_transport_id *target_cp_transport_id(struct t10_transport_id *src)
+{
+	struct t10_transport_id *dst;
+
+	dst = kzalloc(sizeof(*dst), GFP_KERNEL);
+	if (!dst)
+		return NULL;
+	dst->format = src->format;
+	dst->proto = src->proto;
+
+	switch (src->proto) {
+	case SCSI_PROTOCOL_FCP:
+		dst->fcp.port_name = kstrdup(src->fcp.port_name, GFP_KERNEL);
+		if (!dst->fcp.port_name)
+			goto free_tpid;
+		break;
+	case SCSI_PROTOCOL_SBP:
+		dst->sbp.name = kstrdup(src->sbp.name, GFP_KERNEL);
+		if (!dst->sbp.name)
+			goto free_tpid;
+		break;
+	case SCSI_PROTOCOL_SRP:
+		dst->srp.port_id = kstrdup(src->srp.port_id, GFP_KERNEL);
+		if (!dst->srp.port_id)
+			goto free_tpid;
+		break;
+	case SCSI_PROTOCOL_SAS:
+		dst->sas.addr = kstrdup(src->sas.addr, GFP_KERNEL);
+		if (!dst->sas.addr)
+			goto free_tpid;
+		break;
+	case SCSI_PROTOCOL_ISCSI:
+		dst->iscsi.name = kstrdup(src->iscsi.name, GFP_KERNEL);
+		if (!dst->iscsi.name)
+			goto free_tpid;
+
+		if (src->format) {
+			dst->iscsi.session_id = kstrdup(src->iscsi.session_id,
+							GFP_KERNEL);
+			if (!dst->iscsi.session_id) {
+				kfree(dst->iscsi.name);
+				goto free_tpid;
+			}
+		}
+		break;
+	default:
+		pr_err("Unknown proto_id: 0x%02x\n", src->proto);
+		return NULL;
+	}
+
+	return dst;
+
+free_tpid:
+	kfree(dst);
+	return NULL;
+}
+EXPORT_SYMBOL(target_cp_transport_id);
+
+void target_free_transport_id(struct t10_transport_id *tpid)
+{
+	if (!tpid)
+		return;
+
+	switch (tpid->proto) {
+	case SCSI_PROTOCOL_FCP:
+		kfree(tpid->fcp.port_name);
+		break;
+	case SCSI_PROTOCOL_SBP:
+		kfree(tpid->sbp.name);
+		break;
+	case SCSI_PROTOCOL_SRP:
+		kfree(tpid->srp.port_id);
+		break;
+	case SCSI_PROTOCOL_SAS:
+		kfree(tpid->sas.addr);
+		break;
+	case SCSI_PROTOCOL_ISCSI:
+		kfree(tpid->iscsi.name);
+		kfree(tpid->iscsi.session_id);
+		break;
+	default:
+		pr_err("Unknown proto_id: 0x%02x\n", tpid->proto);
+		return;
+	}
+	kfree(tpid);
+}
diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h
index 8533444..5e016aa 100644
--- a/drivers/target/target_core_internal.h
+++ b/drivers/target/target_core_internal.h
@@ -104,6 +104,7 @@ int	target_get_pr_transport_id(struct se_node_acl *nacl,
 		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);
+void target_free_transport_id(struct t10_transport_id *tpid);
 
 /* target_core_hba.c */
 struct se_hba *core_alloc_hba(const char *, u32, u32);
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 0ae9e60..adf4a84 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -416,12 +416,13 @@ void transport_register_session(
 struct se_session *
 target_setup_session(struct se_portal_group *tpg,
 		     unsigned int tag_num, unsigned int tag_size,
-		     enum target_prot_op prot_op,
+		     enum target_prot_op prot_op, struct t10_transport_id *tpid,
 		     const char *initiatorname, void *private,
 		     int (*callback)(struct se_portal_group *,
 				     struct se_session *, void *))
 {
 	struct se_session *sess;
+	int rc;
 
 	/*
 	 * If the fabric driver is using percpu-ida based pre allocation
@@ -435,6 +436,12 @@ struct se_session *
 	if (IS_ERR(sess))
 		return sess;
 
+	sess->tpid = target_cp_transport_id(tpid);
+	if (!sess->tpid) {
+		rc = -ENOMEM;
+		goto free_sess;
+	}
+
 	sess->se_node_acl = core_tpg_check_initiator_node_acl(tpg,
 					(unsigned char *)initiatorname);
 	if (!sess->se_node_acl) {
@@ -446,15 +453,17 @@ struct se_session *
 	 * required before transport_register_session().
 	 */
 	if (callback != NULL) {
-		int rc = callback(tpg, sess, private);
-		if (rc) {
-			transport_free_session(sess);
-			return ERR_PTR(rc);
-		}
+		rc = callback(tpg, sess, private);
+		if (rc)
+			goto free_sess;
 	}
 
 	transport_register_session(tpg, sess->se_node_acl, sess, private);
 	return sess;
+
+free_sess:
+	transport_free_session(sess);
+	return ERR_PTR(rc);
 }
 EXPORT_SYMBOL(target_setup_session);
 
@@ -579,6 +588,7 @@ void transport_free_session(struct se_session *se_sess)
 		sbitmap_queue_free(&se_sess->sess_tag_pool);
 		kvfree(se_sess->sess_cmd_map);
 	}
+	target_free_transport_id(se_sess->tpid);
 	percpu_ref_exit(&se_sess->cmd_count);
 	kmem_cache_free(se_sess_cache, se_sess);
 }
diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c
index 4fd6a1d..f261756 100644
--- a/drivers/target/tcm_fc/tfc_sess.c
+++ b/drivers/target/tcm_fc/tfc_sess.c
@@ -208,6 +208,7 @@ static struct ft_sess *ft_sess_create(struct ft_tport *tport, u32 port_id,
 				      struct fc_rport_priv *rdata)
 {
 	struct se_portal_group *se_tpg = &tport->tpg->se_tpg;
+	struct t10_transport_id tpid;
 	struct ft_sess *sess;
 	struct hlist_head *head;
 	unsigned char initiatorname[TRANSPORT_IQN_LEN];
@@ -227,10 +228,15 @@ static struct ft_sess *ft_sess_create(struct ft_tport *tport, u32 port_id,
 	sess->tport = tport;
 	sess->port_id = port_id;
 
+	memset(&tpid, 0, sizeof(tpid));
+	tpid.proto = SCSI_PROTOCOL_FCP;
+	tpid.fcp.port_name = &initiatorname[0];
+
 	sess->se_sess = target_setup_session(se_tpg, TCM_FC_DEFAULT_TAGS,
 					     sizeof(struct ft_cmd),
-					     TARGET_PROT_NORMAL, &initiatorname[0],
-					     sess, ft_sess_alloc_cb);
+					     TARGET_PROT_NORMAL, &tpid,
+					     &initiatorname[0], sess,
+					     ft_sess_alloc_cb);
 	if (IS_ERR(sess->se_sess)) {
 		int rc = PTR_ERR(sess->se_sess);
 		kfree(sess);
diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c
index 3650493..e282eb9 100644
--- a/drivers/usb/gadget/function/f_tcm.c
+++ b/drivers/usb/gadget/function/f_tcm.c
@@ -1564,6 +1564,7 @@ static int usbg_alloc_sess_cb(struct se_portal_group *se_tpg,
 static int tcm_usbg_make_nexus(struct usbg_tpg *tpg, char *name)
 {
 	struct tcm_usbg_nexus *tv_nexus;
+	struct t10_transport_id tpid;
 	int ret = 0;
 
 	mutex_lock(&tpg->tpg_mutex);
@@ -1579,11 +1580,17 @@ static int tcm_usbg_make_nexus(struct usbg_tpg *tpg, char *name)
 		goto out_unlock;
 	}
 
+	memset(&tpid, 0, sizeof(tpid));
+	tpid.proto = tpg->se_tpg.proto_id;
+	/* SPC does not assign a proto id for USB-SCSI so we use SAS naming */
+	tpid.sas.addr = name;
+
 	tv_nexus->tvn_se_sess = target_setup_session(&tpg->se_tpg,
 						     USB_G_DEFAULT_SESSION_TAGS,
 						     sizeof(struct usbg_cmd),
-						     TARGET_PROT_NORMAL, name,
-						     tv_nexus, usbg_alloc_sess_cb);
+						     TARGET_PROT_NORMAL, &tpid,
+						     name, tv_nexus,
+						     usbg_alloc_sess_cb);
 	if (IS_ERR(tv_nexus->tvn_se_sess)) {
 #define MAKE_NEXUS_MSG "core_tpg_check_initiator_node_acl() failed for %s\n"
 		pr_debug(MAKE_NEXUS_MSG, name);
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 0b949a1..bc377ee 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -1937,10 +1937,10 @@ static int vhost_scsi_nexus_cb(struct se_portal_group *se_tpg,
 	return -ENOMEM;
 }
 
-static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg,
-				const char *name)
+static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg, char *name)
 {
 	struct vhost_scsi_nexus *tv_nexus;
+	struct t10_transport_id tpid;
 
 	mutex_lock(&tpg->tv_tpg_mutex);
 	if (tpg->tpg_nexus) {
@@ -1949,6 +1949,25 @@ static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg,
 		return -EEXIST;
 	}
 
+	memset(&tpid, 0, sizeof(tpid));
+	tpid.proto = tpg->se_tpg.proto_id;
+
+	switch (tpid.proto) {
+	case SCSI_PROTOCOL_SAS:
+		tpid.sas.addr = name;
+		break;
+	case SCSI_PROTOCOL_FCP:
+		tpid.fcp.port_name = name;
+		break;
+	case SCSI_PROTOCOL_ISCSI:
+		/* we only support format=0 */
+		tpid.iscsi.name = name;
+		break;
+	default:
+		mutex_unlock(&tpg->tv_tpg_mutex);
+		return -EINVAL;
+	}
+
 	tv_nexus = kzalloc(sizeof(*tv_nexus), GFP_KERNEL);
 	if (!tv_nexus) {
 		mutex_unlock(&tpg->tv_tpg_mutex);
@@ -1964,7 +1983,7 @@ static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg,
 					VHOST_SCSI_DEFAULT_TAGS,
 					sizeof(struct vhost_scsi_cmd),
 					TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS,
-					(unsigned char *)name, tv_nexus,
+					&tpid, (unsigned char *)name, tv_nexus,
 					vhost_scsi_nexus_cb);
 	if (IS_ERR(tv_nexus->tvn_se_sess)) {
 		mutex_unlock(&tpg->tv_tpg_mutex);
diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
index ba0942e..0855a77f 100644
--- a/drivers/xen/xen-scsiback.c
+++ b/drivers/xen/xen-scsiback.c
@@ -1507,10 +1507,10 @@ static int scsiback_alloc_sess_cb(struct se_portal_group *se_tpg,
 	return 0;
 }
 
-static int scsiback_make_nexus(struct scsiback_tpg *tpg,
-				const char *name)
+static int scsiback_make_nexus(struct scsiback_tpg *tpg, char *name)
 {
 	struct scsiback_nexus *tv_nexus;
+	struct t10_transport_id tpid;
 	int ret = 0;
 
 	mutex_lock(&tpg->tv_tpg_mutex);
@@ -1520,6 +1520,25 @@ static int scsiback_make_nexus(struct scsiback_tpg *tpg,
 		goto out_unlock;
 	}
 
+	memset(&tpid, 0, sizeof(tpid));
+	tpid.proto = tpg->se_tpg.proto_id;
+
+	switch (tpid.proto) {
+	case SCSI_PROTOCOL_SAS:
+		tpid.sas.addr = name;
+		break;
+	case SCSI_PROTOCOL_FCP:
+		tpid.fcp.port_name = name;
+		break;
+	case SCSI_PROTOCOL_ISCSI:
+		/* we only support format=0 */
+		tpid.iscsi.name = name;
+		break;
+	default:
+		ret =-EINVAL;
+		goto out_unlock;
+	}
+
 	tv_nexus = kzalloc(sizeof(struct scsiback_nexus), GFP_KERNEL);
 	if (!tv_nexus) {
 		ret = -ENOMEM;
@@ -1529,8 +1548,9 @@ static int scsiback_make_nexus(struct scsiback_tpg *tpg,
 	tv_nexus->tvn_se_sess = target_setup_session(&tpg->se_tpg,
 						     VSCSI_DEFAULT_SESSION_TAGS,
 						     sizeof(struct vscsibk_pend),
-						     TARGET_PROT_NORMAL, name,
-						     tv_nexus, scsiback_alloc_sess_cb);
+						     TARGET_PROT_NORMAL, &tpid,
+						     name, tv_nexus,
+						     scsiback_alloc_sess_cb);
 	if (IS_ERR(tv_nexus->tvn_se_sess)) {
 		kfree(tv_nexus);
 		ret = -ENOMEM;
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 1728e88..cd440ea 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -333,6 +333,29 @@ struct t10_wwn {
 	struct list_head t10_vpd_list;
 };
 
+struct t10_transport_id {
+	union {
+		struct {
+			char *port_name;
+		} fcp;
+		struct {
+			char *addr;
+		} sas;
+		struct {
+			char *name;
+		} sbp;
+		struct {
+			char *port_id;
+		} srp;
+		struct {
+			char *name;
+			char *session_id;
+		} iscsi;
+	};
+	u8 format;
+	u8 proto;
+};
+
 struct t10_pr_registration {
 	/* Used for fabrics that contain WWN+ISID */
 #define PR_REG_ISID_LEN				16
@@ -605,6 +628,7 @@ static inline struct se_node_acl *fabric_stat_to_nacl(struct config_item *item)
 struct se_session {
 	unsigned		sess_tearing_down:1;
 	u64			sess_bin_isid;
+	struct t10_transport_id	*tpid;
 	enum target_prot_op	sup_prot_ops;
 	enum target_prot_type	sess_prot_type;
 	struct se_node_acl	*se_node_acl;
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
index 063f133..6b8a6bc 100644
--- a/include/target/target_core_fabric.h
+++ b/include/target/target_core_fabric.h
@@ -125,9 +125,10 @@ struct target_core_fabric_ops {
 int target_depend_item(struct config_item *item);
 void target_undepend_item(struct config_item *item);
 
+struct t10_transport_id *target_cp_transport_id(struct t10_transport_id *);
 struct se_session *target_setup_session(struct se_portal_group *,
 		unsigned int, unsigned int, enum target_prot_op prot_op,
-		const char *, void *,
+		struct t10_transport_id *, const char *, void *,
 		int (*callback)(struct se_portal_group *,
 				struct se_session *, void *));
 void target_remove_session(struct se_session *);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [RFC PATCH 03/12] iscsi target: setup transport_id
  2020-04-20 19:14 ` Mike Christie
@ 2020-04-20 19:14   ` Mike Christie
  -1 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel
  Cc: Mike Christie

The iscsi target does its own session setup. This patch updates the
driver so it sets up the transport id.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 drivers/target/iscsi/iscsi_target_nego.c | 38 ++++++++++++++++++++++++++++----
 1 file changed, 34 insertions(+), 4 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c
index 685d771..dd9bfa7 100644
--- a/drivers/target/iscsi/iscsi_target_nego.c
+++ b/drivers/target/iscsi/iscsi_target_nego.c
@@ -1032,6 +1032,26 @@ static void iscsi_initiatorname_tolower(
 	}
 }
 
+static int iscsi_setup_i_tpid(struct iscsi_session *sess, char *iname)
+{
+	struct t10_transport_id tpid;
+	char isid_buf[13];
+
+	sprintf(isid_buf, "%6phN", sess->isid);
+
+	memset(&tpid, 0, sizeof(tpid));
+	tpid.proto = SCSI_PROTOCOL_ISCSI;
+	tpid.format = 1;
+	tpid.iscsi.name = iname;
+	tpid.iscsi.session_id = isid_buf;
+
+	sess->se_sess->tpid = target_cp_transport_id(&tpid);
+	if (!sess->se_sess->tpid)
+		return -ENOMEM;
+
+	return 0;
+}
+
 /*
  * Processes the first Login Request..
  */
@@ -1260,11 +1280,21 @@ int iscsi_target_locate_portal(
 	tag_size = sizeof(struct iscsi_cmd) + conn->conn_transport->priv_size;
 
 	ret = transport_alloc_session_tags(sess->se_sess, tag_num, tag_size);
-	if (ret < 0) {
-		iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
-				    ISCSI_LOGIN_STATUS_NO_RESOURCES);
-		ret = -1;
+	if (ret < 0)
+		goto return_oom;
+
+	if (conn->tpg != iscsit_global->discovery_tpg) {
+		if (iscsi_setup_i_tpid(sess, i_buf))
+			/* tags and nacl released when session is freed */
+			goto return_oom;
 	}
+
+	goto out;
+
+return_oom:
+	iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
+			    ISCSI_LOGIN_STATUS_NO_RESOURCES);
+	ret = -1;
 out:
 	kfree(tmpbuf);
 	return ret;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [RFC PATCH 03/12] iscsi target: setup transport_id
@ 2020-04-20 19:14   ` Mike Christie
  0 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel
  Cc: Mike Christie

The iscsi target does its own session setup. This patch updates the
driver so it sets up the transport id.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 drivers/target/iscsi/iscsi_target_nego.c | 38 ++++++++++++++++++++++++++++----
 1 file changed, 34 insertions(+), 4 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c
index 685d771..dd9bfa7 100644
--- a/drivers/target/iscsi/iscsi_target_nego.c
+++ b/drivers/target/iscsi/iscsi_target_nego.c
@@ -1032,6 +1032,26 @@ static void iscsi_initiatorname_tolower(
 	}
 }
 
+static int iscsi_setup_i_tpid(struct iscsi_session *sess, char *iname)
+{
+	struct t10_transport_id tpid;
+	char isid_buf[13];
+
+	sprintf(isid_buf, "%6phN", sess->isid);
+
+	memset(&tpid, 0, sizeof(tpid));
+	tpid.proto = SCSI_PROTOCOL_ISCSI;
+	tpid.format = 1;
+	tpid.iscsi.name = iname;
+	tpid.iscsi.session_id = isid_buf;
+
+	sess->se_sess->tpid = target_cp_transport_id(&tpid);
+	if (!sess->se_sess->tpid)
+		return -ENOMEM;
+
+	return 0;
+}
+
 /*
  * Processes the first Login Request..
  */
@@ -1260,11 +1280,21 @@ int iscsi_target_locate_portal(
 	tag_size = sizeof(struct iscsi_cmd) + conn->conn_transport->priv_size;
 
 	ret = transport_alloc_session_tags(sess->se_sess, tag_num, tag_size);
-	if (ret < 0) {
-		iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
-				    ISCSI_LOGIN_STATUS_NO_RESOURCES);
-		ret = -1;
+	if (ret < 0)
+		goto return_oom;
+
+	if (conn->tpg != iscsit_global->discovery_tpg) {
+		if (iscsi_setup_i_tpid(sess, i_buf))
+			/* tags and nacl released when session is freed */
+			goto return_oom;
 	}
+
+	goto out;
+
+return_oom:
+	iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
+			    ISCSI_LOGIN_STATUS_NO_RESOURCES);
+	ret = -1;
 out:
 	kfree(tmpbuf);
 	return ret;
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [RFC PATCH 04/12] target: use tpid in target_stat_iport_port_ident_show
  2020-04-20 19:14 ` Mike Christie
@ 2020-04-20 19:14   ` Mike Christie
  -1 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel
  Cc: Mike Christie

Use the tpid session id instead of sess_get_initiator_sid.

Note that for userspace compat this patch continues the behavior:

1. Still add the "+i+" even if there is no session_id.
2. Use the acl initiatorname instead of the transportID port/addr/name.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 drivers/target/target_core_fabric_lib.c |  7 +++++++
 drivers/target/target_core_internal.h   |  1 +
 drivers/target/target_core_stat.c       | 12 ++++++------
 3 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/target/target_core_fabric_lib.c b/drivers/target/target_core_fabric_lib.c
index 39b0e5e..6a53e16 100644
--- a/drivers/target/target_core_fabric_lib.c
+++ b/drivers/target/target_core_fabric_lib.c
@@ -508,3 +508,10 @@ void target_free_transport_id(struct t10_transport_id *tpid)
 	}
 	kfree(tpid);
 }
+
+char *transport_id_get_sid(struct t10_transport_id *tpid)
+{
+	if (tpid->proto == SCSI_PROTOCOL_ISCSI)
+		return tpid->iscsi.session_id;
+	return NULL;
+}
diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h
index 5e016aa..efc5449 100644
--- a/drivers/target/target_core_internal.h
+++ b/drivers/target/target_core_internal.h
@@ -105,6 +105,7 @@ 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);
 void target_free_transport_id(struct t10_transport_id *tpid);
+char *transport_id_get_sid(struct t10_transport_id *tpid);
 
 /* target_core_hba.c */
 struct se_hba *core_alloc_hba(const char *, u32, u32);
diff --git a/drivers/target/target_core_stat.c b/drivers/target/target_core_stat.c
index 237309d..cc9c966 100644
--- a/drivers/target/target_core_stat.c
+++ b/drivers/target/target_core_stat.c
@@ -1309,8 +1309,8 @@ static ssize_t target_stat_iport_port_ident_show(struct config_item *item,
 	struct se_node_acl *nacl = lacl->se_lun_nacl;
 	struct se_session *se_sess;
 	struct se_portal_group *tpg;
+	char *session_id = NULL;
 	ssize_t ret;
-	unsigned char buf[64];
 
 	spin_lock_irq(&nacl->nacl_sess_lock);
 	se_sess = nacl->nacl_sess;
@@ -1319,13 +1319,13 @@ static ssize_t target_stat_iport_port_ident_show(struct config_item *item,
 		return -ENODEV;
 	}
 
+	session_id = transport_id_get_sid(se_sess->tpid);
+	if (!session_id)
+		session_id = "";
 	tpg = nacl->se_tpg;
 	/* scsiAttIntrPortName+scsiAttIntrPortIdentifier */
-	memset(buf, 0, 64);
-	if (tpg->se_tpg_tfo->sess_get_initiator_sid != NULL)
-		tpg->se_tpg_tfo->sess_get_initiator_sid(se_sess, buf, 64);
-
-	ret = snprintf(page, PAGE_SIZE, "%s+i+%s\n", nacl->initiatorname, buf);
+	ret = snprintf(page, PAGE_SIZE, "%s+i+%s\n", nacl->initiatorname,
+		       session_id);
 	spin_unlock_irq(&nacl->nacl_sess_lock);
 	return ret;
 }
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [RFC PATCH 04/12] target: use tpid in target_stat_iport_port_ident_show
@ 2020-04-20 19:14   ` Mike Christie
  0 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel
  Cc: Mike Christie

Use the tpid session id instead of sess_get_initiator_sid.

Note that for userspace compat this patch continues the behavior:

1. Still add the "+i+" even if there is no session_id.
2. Use the acl initiatorname instead of the transportID port/addr/name.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 drivers/target/target_core_fabric_lib.c |  7 +++++++
 drivers/target/target_core_internal.h   |  1 +
 drivers/target/target_core_stat.c       | 12 ++++++------
 3 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/target/target_core_fabric_lib.c b/drivers/target/target_core_fabric_lib.c
index 39b0e5e..6a53e16 100644
--- a/drivers/target/target_core_fabric_lib.c
+++ b/drivers/target/target_core_fabric_lib.c
@@ -508,3 +508,10 @@ void target_free_transport_id(struct t10_transport_id *tpid)
 	}
 	kfree(tpid);
 }
+
+char *transport_id_get_sid(struct t10_transport_id *tpid)
+{
+	if (tpid->proto == SCSI_PROTOCOL_ISCSI)
+		return tpid->iscsi.session_id;
+	return NULL;
+}
diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h
index 5e016aa..efc5449 100644
--- a/drivers/target/target_core_internal.h
+++ b/drivers/target/target_core_internal.h
@@ -105,6 +105,7 @@ 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);
 void target_free_transport_id(struct t10_transport_id *tpid);
+char *transport_id_get_sid(struct t10_transport_id *tpid);
 
 /* target_core_hba.c */
 struct se_hba *core_alloc_hba(const char *, u32, u32);
diff --git a/drivers/target/target_core_stat.c b/drivers/target/target_core_stat.c
index 237309d..cc9c966 100644
--- a/drivers/target/target_core_stat.c
+++ b/drivers/target/target_core_stat.c
@@ -1309,8 +1309,8 @@ static ssize_t target_stat_iport_port_ident_show(struct config_item *item,
 	struct se_node_acl *nacl = lacl->se_lun_nacl;
 	struct se_session *se_sess;
 	struct se_portal_group *tpg;
+	char *session_id = NULL;
 	ssize_t ret;
-	unsigned char buf[64];
 
 	spin_lock_irq(&nacl->nacl_sess_lock);
 	se_sess = nacl->nacl_sess;
@@ -1319,13 +1319,13 @@ static ssize_t target_stat_iport_port_ident_show(struct config_item *item,
 		return -ENODEV;
 	}
 
+	session_id = transport_id_get_sid(se_sess->tpid);
+	if (!session_id)
+		session_id = "";
 	tpg = nacl->se_tpg;
 	/* scsiAttIntrPortName+scsiAttIntrPortIdentifier */
-	memset(buf, 0, 64);
-	if (tpg->se_tpg_tfo->sess_get_initiator_sid != NULL)
-		tpg->se_tpg_tfo->sess_get_initiator_sid(se_sess, buf, 64);
-
-	ret = snprintf(page, PAGE_SIZE, "%s+i+%s\n", nacl->initiatorname, buf);
+	ret = snprintf(page, PAGE_SIZE, "%s+i+%s\n", nacl->initiatorname,
+		       session_id);
 	spin_unlock_irq(&nacl->nacl_sess_lock);
 	return ret;
 }
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [RFC PATCH 05/12] target: drop sess_get_initiator_sid from PR code
  2020-04-20 19:14 ` Mike Christie
@ 2020-04-20 19:14   ` Mike Christie
  -1 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel
  Cc: Mike Christie

Use the transport id session id.

Note: this just converts __transport_register_session. It keeps the sid
copying bug. That fix is still being discussed, and it involves deep
interaction with the core PGR code, so it should be done in another
patchset.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 drivers/target/target_core_pr.c        | 24 +++++-------------------
 drivers/target/target_core_transport.c | 11 ++++-------
 2 files changed, 9 insertions(+), 26 deletions(-)

diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
index cd2d32f..251caf9 100644
--- a/drivers/target/target_core_pr.c
+++ b/drivers/target/target_core_pr.c
@@ -1204,17 +1204,8 @@ static struct t10_pr_registration *core_scsi3_locate_pr_reg(
 	struct se_node_acl *nacl,
 	struct se_session *sess)
 {
-	struct se_portal_group *tpg = nacl->se_tpg;
-	unsigned char buf[PR_REG_ISID_LEN], *isid_ptr = NULL;
-
-	if (tpg->se_tpg_tfo->sess_get_initiator_sid != NULL) {
-		memset(&buf[0], 0, PR_REG_ISID_LEN);
-		tpg->se_tpg_tfo->sess_get_initiator_sid(sess, &buf[0],
-					PR_REG_ISID_LEN);
-		isid_ptr = &buf[0];
-	}
-
-	return __core_scsi3_locate_pr_reg(dev, nacl, isid_ptr);
+	return __core_scsi3_locate_pr_reg(dev, nacl,
+					  transport_id_get_sid(sess->tpid));
 }
 
 static void core_scsi3_put_pr_reg(struct t10_pr_registration *pr_reg)
@@ -1592,7 +1583,7 @@ static void core_scsi3_lunacl_undepend_item(struct se_dev_entry *se_deve)
 			 * SCSI Intiatior TransportID w/ ISIDs is enforced
 			 * for fabric modules (iSCSI) requiring them.
 			 */
-			if (tpg->se_tpg_tfo->sess_get_initiator_sid &&
+			if (transport_id_get_sid(se_sess->tpid) &&
                             dev->dev_attrib.enforce_pr_isids &&
 			    !iport_ptr) {
 				pr_warn("SPC-PR: enforce_pr_isids is set but a isid has not been sent in the SPEC_I_PT data for %s.",
@@ -2057,7 +2048,7 @@ static sense_reason_t core_scsi3_update_and_write_aptpl(struct se_device *dev, b
 	struct se_portal_group *se_tpg;
 	struct t10_pr_registration *pr_reg, *pr_reg_p, *pr_reg_tmp;
 	struct t10_reservation *pr_tmpl = &dev->t10_pr;
-	unsigned char isid_buf[PR_REG_ISID_LEN], *isid_ptr = NULL;
+	unsigned char *isid_ptr = NULL;
 	sense_reason_t ret = TCM_NO_SENSE;
 	int pr_holder = 0, type;
 
@@ -2067,12 +2058,7 @@ static sense_reason_t core_scsi3_update_and_write_aptpl(struct se_device *dev, b
 	}
 	se_tpg = se_sess->se_tpg;
 
-	if (se_tpg->se_tpg_tfo->sess_get_initiator_sid) {
-		memset(&isid_buf[0], 0, PR_REG_ISID_LEN);
-		se_tpg->se_tpg_tfo->sess_get_initiator_sid(se_sess, &isid_buf[0],
-				PR_REG_ISID_LEN);
-		isid_ptr = &isid_buf[0];
-	}
+	isid_ptr = transport_id_get_sid(se_sess->tpid);
 	/*
 	 * Follow logic from spc4r17 Section 5.7.7, Register Behaviors Table 47
 	 */
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index adf4a84..66f0af1 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -343,7 +343,7 @@ void __transport_register_session(
 	void *fabric_sess_ptr)
 {
 	const struct target_core_fabric_ops *tfo = se_tpg->se_tpg_tfo;
-	unsigned char buf[PR_REG_ISID_LEN];
+	unsigned char *sid;
 	unsigned long flags;
 
 	se_sess->se_tpg = se_tpg;
@@ -374,12 +374,9 @@ void __transport_register_session(
 		 * If the fabric module supports an ISID based TransportID,
 		 * save this value in binary from the fabric I_T Nexus now.
 		 */
-		if (se_tpg->se_tpg_tfo->sess_get_initiator_sid != NULL) {
-			memset(&buf[0], 0, PR_REG_ISID_LEN);
-			se_tpg->se_tpg_tfo->sess_get_initiator_sid(se_sess,
-					&buf[0], PR_REG_ISID_LEN);
-			se_sess->sess_bin_isid = get_unaligned_be64(&buf[0]);
-		}
+		sid = transport_id_get_sid(se_sess->tpid);
+		if (sid)
+			se_sess->sess_bin_isid = get_unaligned_be64(sid);
 
 		spin_lock_irqsave(&se_nacl->nacl_sess_lock, flags);
 		/*
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [RFC PATCH 05/12] target: drop sess_get_initiator_sid from PR code
@ 2020-04-20 19:14   ` Mike Christie
  0 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel
  Cc: Mike Christie

Use the transport id session id.

Note: this just converts __transport_register_session. It keeps the sid
copying bug. That fix is still being discussed, and it involves deep
interaction with the core PGR code, so it should be done in another
patchset.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 drivers/target/target_core_pr.c        | 24 +++++-------------------
 drivers/target/target_core_transport.c | 11 ++++-------
 2 files changed, 9 insertions(+), 26 deletions(-)

diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
index cd2d32f..251caf9 100644
--- a/drivers/target/target_core_pr.c
+++ b/drivers/target/target_core_pr.c
@@ -1204,17 +1204,8 @@ static struct t10_pr_registration *core_scsi3_locate_pr_reg(
 	struct se_node_acl *nacl,
 	struct se_session *sess)
 {
-	struct se_portal_group *tpg = nacl->se_tpg;
-	unsigned char buf[PR_REG_ISID_LEN], *isid_ptr = NULL;
-
-	if (tpg->se_tpg_tfo->sess_get_initiator_sid != NULL) {
-		memset(&buf[0], 0, PR_REG_ISID_LEN);
-		tpg->se_tpg_tfo->sess_get_initiator_sid(sess, &buf[0],
-					PR_REG_ISID_LEN);
-		isid_ptr = &buf[0];
-	}
-
-	return __core_scsi3_locate_pr_reg(dev, nacl, isid_ptr);
+	return __core_scsi3_locate_pr_reg(dev, nacl,
+					  transport_id_get_sid(sess->tpid));
 }
 
 static void core_scsi3_put_pr_reg(struct t10_pr_registration *pr_reg)
@@ -1592,7 +1583,7 @@ static void core_scsi3_lunacl_undepend_item(struct se_dev_entry *se_deve)
 			 * SCSI Intiatior TransportID w/ ISIDs is enforced
 			 * for fabric modules (iSCSI) requiring them.
 			 */
-			if (tpg->se_tpg_tfo->sess_get_initiator_sid &&
+			if (transport_id_get_sid(se_sess->tpid) &&
                             dev->dev_attrib.enforce_pr_isids &&
 			    !iport_ptr) {
 				pr_warn("SPC-PR: enforce_pr_isids is set but a isid has not been sent in the SPEC_I_PT data for %s.",
@@ -2057,7 +2048,7 @@ static sense_reason_t core_scsi3_update_and_write_aptpl(struct se_device *dev, b
 	struct se_portal_group *se_tpg;
 	struct t10_pr_registration *pr_reg, *pr_reg_p, *pr_reg_tmp;
 	struct t10_reservation *pr_tmpl = &dev->t10_pr;
-	unsigned char isid_buf[PR_REG_ISID_LEN], *isid_ptr = NULL;
+	unsigned char *isid_ptr = NULL;
 	sense_reason_t ret = TCM_NO_SENSE;
 	int pr_holder = 0, type;
 
@@ -2067,12 +2058,7 @@ static sense_reason_t core_scsi3_update_and_write_aptpl(struct se_device *dev, b
 	}
 	se_tpg = se_sess->se_tpg;
 
-	if (se_tpg->se_tpg_tfo->sess_get_initiator_sid) {
-		memset(&isid_buf[0], 0, PR_REG_ISID_LEN);
-		se_tpg->se_tpg_tfo->sess_get_initiator_sid(se_sess, &isid_buf[0],
-				PR_REG_ISID_LEN);
-		isid_ptr = &isid_buf[0];
-	}
+	isid_ptr = transport_id_get_sid(se_sess->tpid);
 	/*
 	 * Follow logic from spc4r17 Section 5.7.7, Register Behaviors Table 47
 	 */
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index adf4a84..66f0af1 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -343,7 +343,7 @@ void __transport_register_session(
 	void *fabric_sess_ptr)
 {
 	const struct target_core_fabric_ops *tfo = se_tpg->se_tpg_tfo;
-	unsigned char buf[PR_REG_ISID_LEN];
+	unsigned char *sid;
 	unsigned long flags;
 
 	se_sess->se_tpg = se_tpg;
@@ -374,12 +374,9 @@ void __transport_register_session(
 		 * If the fabric module supports an ISID based TransportID,
 		 * save this value in binary from the fabric I_T Nexus now.
 		 */
-		if (se_tpg->se_tpg_tfo->sess_get_initiator_sid != NULL) {
-			memset(&buf[0], 0, PR_REG_ISID_LEN);
-			se_tpg->se_tpg_tfo->sess_get_initiator_sid(se_sess,
-					&buf[0], PR_REG_ISID_LEN);
-			se_sess->sess_bin_isid = get_unaligned_be64(&buf[0]);
-		}
+		sid = transport_id_get_sid(se_sess->tpid);
+		if (sid)
+			se_sess->sess_bin_isid = get_unaligned_be64(sid);
 
 		spin_lock_irqsave(&se_nacl->nacl_sess_lock, flags);
 		/*
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [RFC PATCH 06/12] target: drop sess_get_initiator_sid
  2020-04-20 19:14 ` Mike Christie
@ 2020-04-20 19:14   ` Mike Christie
  -1 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel
  Cc: Mike Christie

sess_get_initiator_sid is no longer used. Drop it.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 drivers/infiniband/ulp/srpt/ib_srpt.c        |  1 -
 drivers/scsi/qla2xxx/tcm_qla2xxx.c           |  2 --
 drivers/target/iscsi/iscsi_target_configfs.c | 13 -------------
 drivers/target/tcm_fc/tfc_conf.c             |  1 -
 drivers/usb/gadget/function/f_tcm.c          |  1 -
 drivers/vhost/scsi.c                         |  1 -
 drivers/xen/xen-scsiback.c                   |  1 -
 include/target/target_core_fabric.h          |  6 ------
 8 files changed, 26 deletions(-)

diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
index caeb32e..4dd2a41 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -3847,7 +3847,6 @@ static ssize_t srpt_wwn_version_show(struct config_item *item, char *buf)
 	.check_stop_free		= srpt_check_stop_free,
 	.close_session			= srpt_close_session,
 	.sess_get_index			= srpt_sess_get_index,
-	.sess_get_initiator_sid		= NULL,
 	.write_pending			= srpt_write_pending,
 	.set_default_node_attributes	= srpt_set_default_node_attrs,
 	.get_cmd_state			= srpt_get_tcm_cmd_state,
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index 42a4025..dc1bddd 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -1833,7 +1833,6 @@ static ssize_t tcm_qla2xxx_wwn_version_show(struct config_item *item,
 	.release_cmd			= tcm_qla2xxx_release_cmd,
 	.close_session			= tcm_qla2xxx_close_session,
 	.sess_get_index			= tcm_qla2xxx_sess_get_index,
-	.sess_get_initiator_sid		= NULL,
 	.write_pending			= tcm_qla2xxx_write_pending,
 	.set_default_node_attributes	= tcm_qla2xxx_set_default_node_attrs,
 	.get_cmd_state			= tcm_qla2xxx_get_cmd_state,
@@ -1873,7 +1872,6 @@ static ssize_t tcm_qla2xxx_wwn_version_show(struct config_item *item,
 	.release_cmd			= tcm_qla2xxx_release_cmd,
 	.close_session			= tcm_qla2xxx_close_session,
 	.sess_get_index			= tcm_qla2xxx_sess_get_index,
-	.sess_get_initiator_sid		= NULL,
 	.write_pending			= tcm_qla2xxx_write_pending,
 	.set_default_node_attributes	= tcm_qla2xxx_set_default_node_attrs,
 	.get_cmd_state			= tcm_qla2xxx_get_cmd_state,
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c
index 42b369f..f640e7a 100644
--- a/drivers/target/iscsi/iscsi_target_configfs.c
+++ b/drivers/target/iscsi/iscsi_target_configfs.c
@@ -1349,18 +1349,6 @@ static u32 lio_sess_get_index(struct se_session *se_sess)
 	return sess->session_index;
 }
 
-static u32 lio_sess_get_initiator_sid(
-	struct se_session *se_sess,
-	unsigned char *buf,
-	u32 size)
-{
-	struct iscsi_session *sess = se_sess->fabric_sess_ptr;
-	/*
-	 * iSCSI Initiator Session Identifier from RFC-3720.
-	 */
-	return snprintf(buf, size, "%6phN", sess->isid);
-}
-
 static int lio_queue_data_in(struct se_cmd *se_cmd)
 {
 	struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
@@ -1542,7 +1530,6 @@ static void lio_release_cmd(struct se_cmd *se_cmd)
 	.release_cmd			= lio_release_cmd,
 	.close_session			= lio_tpg_close_session,
 	.sess_get_index			= lio_sess_get_index,
-	.sess_get_initiator_sid		= lio_sess_get_initiator_sid,
 	.write_pending			= lio_write_pending,
 	.set_default_node_attributes	= lio_set_default_node_attributes,
 	.get_cmd_state			= iscsi_get_cmd_state,
diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c
index 1a38c98..870b7bb 100644
--- a/drivers/target/tcm_fc/tfc_conf.c
+++ b/drivers/target/tcm_fc/tfc_conf.c
@@ -427,7 +427,6 @@ static u32 ft_tpg_get_inst_index(struct se_portal_group *se_tpg)
 	.release_cmd =			ft_release_cmd,
 	.close_session =		ft_sess_close,
 	.sess_get_index =		ft_sess_get_index,
-	.sess_get_initiator_sid =	NULL,
 	.write_pending =		ft_write_pending,
 	.set_default_node_attributes =	ft_set_default_node_attr,
 	.get_cmd_state =		ft_get_cmd_state,
diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c
index e282eb9..88319b9 100644
--- a/drivers/usb/gadget/function/f_tcm.c
+++ b/drivers/usb/gadget/function/f_tcm.c
@@ -1722,7 +1722,6 @@ static int usbg_check_stop_free(struct se_cmd *se_cmd)
 	.tpg_get_inst_index		= usbg_tpg_get_inst_index,
 	.release_cmd			= usbg_release_cmd,
 	.sess_get_index			= usbg_sess_get_index,
-	.sess_get_initiator_sid		= NULL,
 	.write_pending			= usbg_send_write_request,
 	.set_default_node_attributes	= usbg_set_default_node_attrs,
 	.get_cmd_state			= usbg_get_cmd_state,
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index bc377ee..7ad7a92 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -2310,7 +2310,6 @@ static void vhost_scsi_drop_tport(struct se_wwn *wwn)
 	.release_cmd			= vhost_scsi_release_cmd,
 	.check_stop_free		= vhost_scsi_check_stop_free,
 	.sess_get_index			= vhost_scsi_sess_get_index,
-	.sess_get_initiator_sid		= NULL,
 	.write_pending			= vhost_scsi_write_pending,
 	.set_default_node_attributes	= vhost_scsi_set_default_node_attrs,
 	.get_cmd_state			= vhost_scsi_get_cmd_state,
diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
index 0855a77f..6f9b4f7 100644
--- a/drivers/xen/xen-scsiback.c
+++ b/drivers/xen/xen-scsiback.c
@@ -1831,7 +1831,6 @@ static int scsiback_check_false(struct se_portal_group *se_tpg)
 	.check_stop_free		= scsiback_check_stop_free,
 	.release_cmd			= scsiback_release_cmd,
 	.sess_get_index			= scsiback_sess_get_index,
-	.sess_get_initiator_sid		= NULL,
 	.write_pending			= scsiback_write_pending,
 	.set_default_node_attributes	= scsiback_set_default_node_attrs,
 	.get_cmd_state			= scsiback_get_cmd_state,
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
index 6b8a6bc..0c1720d 100644
--- a/include/target/target_core_fabric.h
+++ b/include/target/target_core_fabric.h
@@ -67,12 +67,6 @@ struct target_core_fabric_ops {
 	void (*release_cmd)(struct se_cmd *);
 	void (*close_session)(struct se_session *);
 	u32 (*sess_get_index)(struct se_session *);
-	/*
-	 * Used only for SCSI fabrics that contain multi-value TransportIDs
-	 * (like iSCSI).  All other SCSI fabrics should set this to NULL.
-	 */
-	u32 (*sess_get_initiator_sid)(struct se_session *,
-				      unsigned char *, u32);
 	int (*write_pending)(struct se_cmd *);
 	void (*set_default_node_attributes)(struct se_node_acl *);
 	int (*get_cmd_state)(struct se_cmd *);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [RFC PATCH 06/12] target: drop sess_get_initiator_sid
@ 2020-04-20 19:14   ` Mike Christie
  0 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel
  Cc: Mike Christie

sess_get_initiator_sid is no longer used. Drop it.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 drivers/infiniband/ulp/srpt/ib_srpt.c        |  1 -
 drivers/scsi/qla2xxx/tcm_qla2xxx.c           |  2 --
 drivers/target/iscsi/iscsi_target_configfs.c | 13 -------------
 drivers/target/tcm_fc/tfc_conf.c             |  1 -
 drivers/usb/gadget/function/f_tcm.c          |  1 -
 drivers/vhost/scsi.c                         |  1 -
 drivers/xen/xen-scsiback.c                   |  1 -
 include/target/target_core_fabric.h          |  6 ------
 8 files changed, 26 deletions(-)

diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
index caeb32e..4dd2a41 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -3847,7 +3847,6 @@ static ssize_t srpt_wwn_version_show(struct config_item *item, char *buf)
 	.check_stop_free		= srpt_check_stop_free,
 	.close_session			= srpt_close_session,
 	.sess_get_index			= srpt_sess_get_index,
-	.sess_get_initiator_sid		= NULL,
 	.write_pending			= srpt_write_pending,
 	.set_default_node_attributes	= srpt_set_default_node_attrs,
 	.get_cmd_state			= srpt_get_tcm_cmd_state,
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index 42a4025..dc1bddd 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -1833,7 +1833,6 @@ static ssize_t tcm_qla2xxx_wwn_version_show(struct config_item *item,
 	.release_cmd			= tcm_qla2xxx_release_cmd,
 	.close_session			= tcm_qla2xxx_close_session,
 	.sess_get_index			= tcm_qla2xxx_sess_get_index,
-	.sess_get_initiator_sid		= NULL,
 	.write_pending			= tcm_qla2xxx_write_pending,
 	.set_default_node_attributes	= tcm_qla2xxx_set_default_node_attrs,
 	.get_cmd_state			= tcm_qla2xxx_get_cmd_state,
@@ -1873,7 +1872,6 @@ static ssize_t tcm_qla2xxx_wwn_version_show(struct config_item *item,
 	.release_cmd			= tcm_qla2xxx_release_cmd,
 	.close_session			= tcm_qla2xxx_close_session,
 	.sess_get_index			= tcm_qla2xxx_sess_get_index,
-	.sess_get_initiator_sid		= NULL,
 	.write_pending			= tcm_qla2xxx_write_pending,
 	.set_default_node_attributes	= tcm_qla2xxx_set_default_node_attrs,
 	.get_cmd_state			= tcm_qla2xxx_get_cmd_state,
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c
index 42b369f..f640e7a 100644
--- a/drivers/target/iscsi/iscsi_target_configfs.c
+++ b/drivers/target/iscsi/iscsi_target_configfs.c
@@ -1349,18 +1349,6 @@ static u32 lio_sess_get_index(struct se_session *se_sess)
 	return sess->session_index;
 }
 
-static u32 lio_sess_get_initiator_sid(
-	struct se_session *se_sess,
-	unsigned char *buf,
-	u32 size)
-{
-	struct iscsi_session *sess = se_sess->fabric_sess_ptr;
-	/*
-	 * iSCSI Initiator Session Identifier from RFC-3720.
-	 */
-	return snprintf(buf, size, "%6phN", sess->isid);
-}
-
 static int lio_queue_data_in(struct se_cmd *se_cmd)
 {
 	struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
@@ -1542,7 +1530,6 @@ static void lio_release_cmd(struct se_cmd *se_cmd)
 	.release_cmd			= lio_release_cmd,
 	.close_session			= lio_tpg_close_session,
 	.sess_get_index			= lio_sess_get_index,
-	.sess_get_initiator_sid		= lio_sess_get_initiator_sid,
 	.write_pending			= lio_write_pending,
 	.set_default_node_attributes	= lio_set_default_node_attributes,
 	.get_cmd_state			= iscsi_get_cmd_state,
diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c
index 1a38c98..870b7bb 100644
--- a/drivers/target/tcm_fc/tfc_conf.c
+++ b/drivers/target/tcm_fc/tfc_conf.c
@@ -427,7 +427,6 @@ static u32 ft_tpg_get_inst_index(struct se_portal_group *se_tpg)
 	.release_cmd =			ft_release_cmd,
 	.close_session =		ft_sess_close,
 	.sess_get_index =		ft_sess_get_index,
-	.sess_get_initiator_sid =	NULL,
 	.write_pending =		ft_write_pending,
 	.set_default_node_attributes =	ft_set_default_node_attr,
 	.get_cmd_state =		ft_get_cmd_state,
diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c
index e282eb9..88319b9 100644
--- a/drivers/usb/gadget/function/f_tcm.c
+++ b/drivers/usb/gadget/function/f_tcm.c
@@ -1722,7 +1722,6 @@ static int usbg_check_stop_free(struct se_cmd *se_cmd)
 	.tpg_get_inst_index		= usbg_tpg_get_inst_index,
 	.release_cmd			= usbg_release_cmd,
 	.sess_get_index			= usbg_sess_get_index,
-	.sess_get_initiator_sid		= NULL,
 	.write_pending			= usbg_send_write_request,
 	.set_default_node_attributes	= usbg_set_default_node_attrs,
 	.get_cmd_state			= usbg_get_cmd_state,
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index bc377ee..7ad7a92 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -2310,7 +2310,6 @@ static void vhost_scsi_drop_tport(struct se_wwn *wwn)
 	.release_cmd			= vhost_scsi_release_cmd,
 	.check_stop_free		= vhost_scsi_check_stop_free,
 	.sess_get_index			= vhost_scsi_sess_get_index,
-	.sess_get_initiator_sid		= NULL,
 	.write_pending			= vhost_scsi_write_pending,
 	.set_default_node_attributes	= vhost_scsi_set_default_node_attrs,
 	.get_cmd_state			= vhost_scsi_get_cmd_state,
diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
index 0855a77f..6f9b4f7 100644
--- a/drivers/xen/xen-scsiback.c
+++ b/drivers/xen/xen-scsiback.c
@@ -1831,7 +1831,6 @@ static int scsiback_check_false(struct se_portal_group *se_tpg)
 	.check_stop_free		= scsiback_check_stop_free,
 	.release_cmd			= scsiback_release_cmd,
 	.sess_get_index			= scsiback_sess_get_index,
-	.sess_get_initiator_sid		= NULL,
 	.write_pending			= scsiback_write_pending,
 	.set_default_node_attributes	= scsiback_set_default_node_attrs,
 	.get_cmd_state			= scsiback_get_cmd_state,
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
index 6b8a6bc..0c1720d 100644
--- a/include/target/target_core_fabric.h
+++ b/include/target/target_core_fabric.h
@@ -67,12 +67,6 @@ struct target_core_fabric_ops {
 	void (*release_cmd)(struct se_cmd *);
 	void (*close_session)(struct se_session *);
 	u32 (*sess_get_index)(struct se_session *);
-	/*
-	 * Used only for SCSI fabrics that contain multi-value TransportIDs
-	 * (like iSCSI).  All other SCSI fabrics should set this to NULL.
-	 */
-	u32 (*sess_get_initiator_sid)(struct se_session *,
-				      unsigned char *, u32);
 	int (*write_pending)(struct se_cmd *);
 	void (*set_default_node_attributes)(struct se_node_acl *);
 	int (*get_cmd_state)(struct se_cmd *);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [RFC PATCH 07/12] target: add sysfs support
  2020-04-20 19:14 ` Mike Christie
@ 2020-04-20 19:14   ` Mike Christie
  -1 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel
  Cc: Mike Christie

configfs does not work well when the kernel is initiating the creation
of an object we want to export info for and the objects above/below it
are created by the user. There are races/bugs like seen with this patch
and the issue the original bug was trying to fix:

commit f19e4ed1e1edbfa3c9ccb9fed17759b7d6db24c6
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Thu Aug 29 23:13:30 2019 -0400

    configfs_register_group() shouldn't be (and isn't) called in
rmdirable parts

The problem is that for many drivers like qla2xxx, iscsi, etc, session
creation is done by the kernel when there is a login initiated by an
initiator, but we need a common way to export the systems sessions so
tools like targetcli can report basic info like what initaitors are
logged in and daemons like tcmu-runner can track sessions for load
balancing and PGRs.

This patch begins to add a sysfs interface that will initially be used
to export LIO's sessions. The general layout will mirror the lio
configfs tree:

scsi_target /
`-- $fabric_driver
    `-- target_name
        |-- tpgt_1
        |   `-- sessions
        `-- tpgt_2
            `-- sessions

iscsi example:
scsi_target /
`-- iscsi
    `-- iqn.1999-09.com.lio:tgt1
        |-- tpgt_1
        |   `-- sessions
        `-- tpgt_2
            `-- sessions

This initial patch adds only adds the upper layer dirs above the
sessions.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---

V2:
- rename top level dir to scsi_target

 drivers/target/target_core_configfs.c        | 21 ++++++++++++++++++
 drivers/target/target_core_fabric_configfs.c | 32 ++++++++++++++++++++++++++++
 drivers/target/target_core_internal.h        |  1 +
 include/target/target_core_base.h            |  4 ++++
 4 files changed, 58 insertions(+)

diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index e6e1755..7e21b87 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -63,6 +63,8 @@
 	pr_debug("Setup generic %s\n", __stringify(_name));		\
 }
 
+static struct kobject *tcm_core_kobj;
+
 extern struct t10_alua_lu_gp *default_lu_gp;
 
 static LIST_HEAD(g_tf_list);
@@ -245,6 +247,11 @@ static struct config_group *target_core_register_fabric(
 	}
 	pr_debug("Target_Core_ConfigFS: REGISTER -> Located fabric:"
 			" %s\n", tf->tf_ops->fabric_name);
+
+	tf->kobj = kobject_create_and_add(name, tcm_core_kobj);
+	if (!tf->kobj)
+		goto dec_tf;
+
 	/*
 	 * On a successful target_core_get_fabric() look, the returned
 	 * struct target_fabric_configfs *tf will contain a usage reference.
@@ -261,6 +268,10 @@ static struct config_group *target_core_register_fabric(
 	pr_debug("Target_Core_ConfigFS: REGISTER -> Allocated Fabric: %s\n",
 		 config_item_name(&tf->tf_group.cg_item));
 	return &tf->tf_group;
+
+dec_tf:
+	atomic_dec(&tf->tf_access_cnt);
+	return ERR_PTR(-EINVAL);
 }
 
 /*
@@ -283,6 +294,9 @@ static void target_core_deregister_fabric(
 	pr_debug("Target_Core_ConfigFS: DEREGISTER -> Releasing ci"
 			" %s\n", config_item_name(item));
 
+	kobject_del(tf->kobj);
+	kobject_put(tf->kobj);
+
 	configfs_remove_default_groups(&tf->tf_group);
 	config_item_put(item);
 }
@@ -3536,6 +3550,10 @@ static int __init target_core_init_configfs(void)
 
 	target_init_dbroot();
 
+	tcm_core_kobj = kobject_create_and_add("scsi_target", NULL);
+	if (!tcm_core_kobj)
+		goto out;
+
 	return 0;
 
 out:
@@ -3553,6 +3571,9 @@ static int __init target_core_init_configfs(void)
 
 static void __exit target_core_exit_configfs(void)
 {
+	kobject_del(tcm_core_kobj);
+	kobject_put(tcm_core_kobj);
+
 	configfs_remove_default_groups(&alua_lu_gps_group);
 	configfs_remove_default_groups(&alua_group);
 	configfs_remove_default_groups(&target_core_hbagroup);
diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c
index ee85602..4d208e4 100644
--- a/drivers/target/target_core_fabric_configfs.c
+++ b/drivers/target/target_core_fabric_configfs.c
@@ -838,6 +838,14 @@ static struct config_group *target_fabric_make_tpg(
 	if (!se_tpg || IS_ERR(se_tpg))
 		return ERR_PTR(-EINVAL);
 
+	se_tpg->kobj = kobject_create_and_add(name, wwn->kobj);
+	if (!se_tpg->kobj)
+		goto drop_tpg;
+
+	se_tpg->sessions_kobj = kobject_create_and_add("sessions", se_tpg->kobj);
+	if (!se_tpg->sessions_kobj)
+		goto del_tpg_kobj;
+
 	config_group_init_type_name(&se_tpg->tpg_group, name,
 			&tf->tf_tpg_base_cit);
 
@@ -872,6 +880,13 @@ static struct config_group *target_fabric_make_tpg(
 			&se_tpg->tpg_group);
 
 	return &se_tpg->tpg_group;
+
+del_tpg_kobj:
+	kobject_del(se_tpg->kobj);
+	kobject_put(se_tpg->kobj);
+drop_tpg:
+	tf->tf_ops->fabric_drop_tpg(se_tpg);
+	return ERR_PTR(-EINVAL);
 }
 
 static void target_fabric_drop_tpg(
@@ -881,6 +896,12 @@ static void target_fabric_drop_tpg(
 	struct se_portal_group *se_tpg = container_of(to_config_group(item),
 				struct se_portal_group, tpg_group);
 
+	kobject_del(se_tpg->sessions_kobj);
+	kobject_put(se_tpg->sessions_kobj);
+
+	kobject_del(se_tpg->kobj);
+	kobject_put(se_tpg->kobj);
+
 	configfs_remove_default_groups(&se_tpg->tpg_group);
 	config_item_put(item);
 }
@@ -927,6 +948,7 @@ static struct config_group *target_fabric_make_wwn(
 	struct target_fabric_configfs *tf = container_of(group,
 				struct target_fabric_configfs, tf_group);
 	struct se_wwn *wwn;
+	int ret;
 
 	if (!tf->tf_ops->fabric_make_wwn) {
 		pr_err("tf->tf_ops.fabric_make_wwn is NULL\n");
@@ -938,6 +960,9 @@ static struct config_group *target_fabric_make_wwn(
 		return ERR_PTR(-EINVAL);
 
 	wwn->wwn_tf = tf;
+	wwn->kobj = kobject_create_and_add(name, tf->kobj);
+	if (!wwn->kobj)
+		goto drop_wwn;
 
 	config_group_init_type_name(&wwn->wwn_group, name, &tf->tf_tpg_cit);
 
@@ -947,7 +972,12 @@ static struct config_group *target_fabric_make_wwn(
 
 	if (tf->tf_ops->add_wwn_groups)
 		tf->tf_ops->add_wwn_groups(wwn);
+
 	return &wwn->wwn_group;
+
+drop_wwn:
+	tf->tf_ops->fabric_drop_wwn(wwn);
+	return ERR_PTR(ret);
 }
 
 static void target_fabric_drop_wwn(
@@ -957,6 +987,8 @@ static void target_fabric_drop_wwn(
 	struct se_wwn *wwn = container_of(to_config_group(item),
 				struct se_wwn, wwn_group);
 
+	kobject_del(wwn->kobj);
+	kobject_put(wwn->kobj);
 	configfs_remove_default_groups(&wwn->wwn_group);
 	config_item_put(item);
 }
diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h
index efc5449..d242a97 100644
--- a/drivers/target/target_core_internal.h
+++ b/drivers/target/target_core_internal.h
@@ -27,6 +27,7 @@ struct target_backend {
 struct target_fabric_configfs {
 	atomic_t		tf_access_cnt;
 	struct list_head	tf_list;
+	struct kobject		*kobj;
 	struct config_group	tf_group;
 	struct config_group	tf_disc_group;
 	const struct target_core_fabric_ops *tf_ops;
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index cd440ea..b48f8cf 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -8,6 +8,7 @@
 #include <linux/percpu-refcount.h>
 #include <linux/semaphore.h>     /* struct semaphore */
 #include <linux/completion.h>
+#include <linux/kobject.h>
 
 #define TARGET_CORE_VERSION		"v5.0"
 
@@ -909,6 +910,8 @@ struct se_portal_group {
 	/* Pointer to $FABRIC_MOD dependent code */
 	const struct target_core_fabric_ops *se_tpg_tfo;
 	struct se_wwn		*se_tpg_wwn;
+	struct kobject		*kobj;
+	struct kobject		*sessions_kobj;
 	struct config_group	tpg_group;
 	struct config_group	tpg_lun_group;
 	struct config_group	tpg_np_group;
@@ -947,6 +950,7 @@ struct se_wwn {
 	void			*priv;
 	struct config_group	wwn_group;
 	struct config_group	fabric_stat_group;
+	struct kobject		*kobj;
 };
 
 static inline void atomic_inc_mb(atomic_t *v)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [RFC PATCH 07/12] target: add sysfs support
@ 2020-04-20 19:14   ` Mike Christie
  0 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel
  Cc: Mike Christie

configfs does not work well when the kernel is initiating the creation
of an object we want to export info for and the objects above/below it
are created by the user. There are races/bugs like seen with this patch
and the issue the original bug was trying to fix:

commit f19e4ed1e1edbfa3c9ccb9fed17759b7d6db24c6
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Thu Aug 29 23:13:30 2019 -0400

    configfs_register_group() shouldn't be (and isn't) called in
rmdirable parts

The problem is that for many drivers like qla2xxx, iscsi, etc, session
creation is done by the kernel when there is a login initiated by an
initiator, but we need a common way to export the systems sessions so
tools like targetcli can report basic info like what initaitors are
logged in and daemons like tcmu-runner can track sessions for load
balancing and PGRs.

This patch begins to add a sysfs interface that will initially be used
to export LIO's sessions. The general layout will mirror the lio
configfs tree:

scsi_target /
`-- $fabric_driver
    `-- target_name
        |-- tpgt_1
        |   `-- sessions
        `-- tpgt_2
            `-- sessions

iscsi example:
scsi_target /
`-- iscsi
    `-- iqn.1999-09.com.lio:tgt1
        |-- tpgt_1
        |   `-- sessions
        `-- tpgt_2
            `-- sessions

This initial patch adds only adds the upper layer dirs above the
sessions.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---

V2:
- rename top level dir to scsi_target

 drivers/target/target_core_configfs.c        | 21 ++++++++++++++++++
 drivers/target/target_core_fabric_configfs.c | 32 ++++++++++++++++++++++++++++
 drivers/target/target_core_internal.h        |  1 +
 include/target/target_core_base.h            |  4 ++++
 4 files changed, 58 insertions(+)

diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index e6e1755..7e21b87 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -63,6 +63,8 @@
 	pr_debug("Setup generic %s\n", __stringify(_name));		\
 }
 
+static struct kobject *tcm_core_kobj;
+
 extern struct t10_alua_lu_gp *default_lu_gp;
 
 static LIST_HEAD(g_tf_list);
@@ -245,6 +247,11 @@ static struct config_group *target_core_register_fabric(
 	}
 	pr_debug("Target_Core_ConfigFS: REGISTER -> Located fabric:"
 			" %s\n", tf->tf_ops->fabric_name);
+
+	tf->kobj = kobject_create_and_add(name, tcm_core_kobj);
+	if (!tf->kobj)
+		goto dec_tf;
+
 	/*
 	 * On a successful target_core_get_fabric() look, the returned
 	 * struct target_fabric_configfs *tf will contain a usage reference.
@@ -261,6 +268,10 @@ static struct config_group *target_core_register_fabric(
 	pr_debug("Target_Core_ConfigFS: REGISTER -> Allocated Fabric: %s\n",
 		 config_item_name(&tf->tf_group.cg_item));
 	return &tf->tf_group;
+
+dec_tf:
+	atomic_dec(&tf->tf_access_cnt);
+	return ERR_PTR(-EINVAL);
 }
 
 /*
@@ -283,6 +294,9 @@ static void target_core_deregister_fabric(
 	pr_debug("Target_Core_ConfigFS: DEREGISTER -> Releasing ci"
 			" %s\n", config_item_name(item));
 
+	kobject_del(tf->kobj);
+	kobject_put(tf->kobj);
+
 	configfs_remove_default_groups(&tf->tf_group);
 	config_item_put(item);
 }
@@ -3536,6 +3550,10 @@ static int __init target_core_init_configfs(void)
 
 	target_init_dbroot();
 
+	tcm_core_kobj = kobject_create_and_add("scsi_target", NULL);
+	if (!tcm_core_kobj)
+		goto out;
+
 	return 0;
 
 out:
@@ -3553,6 +3571,9 @@ static int __init target_core_init_configfs(void)
 
 static void __exit target_core_exit_configfs(void)
 {
+	kobject_del(tcm_core_kobj);
+	kobject_put(tcm_core_kobj);
+
 	configfs_remove_default_groups(&alua_lu_gps_group);
 	configfs_remove_default_groups(&alua_group);
 	configfs_remove_default_groups(&target_core_hbagroup);
diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c
index ee85602..4d208e4 100644
--- a/drivers/target/target_core_fabric_configfs.c
+++ b/drivers/target/target_core_fabric_configfs.c
@@ -838,6 +838,14 @@ static struct config_group *target_fabric_make_tpg(
 	if (!se_tpg || IS_ERR(se_tpg))
 		return ERR_PTR(-EINVAL);
 
+	se_tpg->kobj = kobject_create_and_add(name, wwn->kobj);
+	if (!se_tpg->kobj)
+		goto drop_tpg;
+
+	se_tpg->sessions_kobj = kobject_create_and_add("sessions", se_tpg->kobj);
+	if (!se_tpg->sessions_kobj)
+		goto del_tpg_kobj;
+
 	config_group_init_type_name(&se_tpg->tpg_group, name,
 			&tf->tf_tpg_base_cit);
 
@@ -872,6 +880,13 @@ static struct config_group *target_fabric_make_tpg(
 			&se_tpg->tpg_group);
 
 	return &se_tpg->tpg_group;
+
+del_tpg_kobj:
+	kobject_del(se_tpg->kobj);
+	kobject_put(se_tpg->kobj);
+drop_tpg:
+	tf->tf_ops->fabric_drop_tpg(se_tpg);
+	return ERR_PTR(-EINVAL);
 }
 
 static void target_fabric_drop_tpg(
@@ -881,6 +896,12 @@ static void target_fabric_drop_tpg(
 	struct se_portal_group *se_tpg = container_of(to_config_group(item),
 				struct se_portal_group, tpg_group);
 
+	kobject_del(se_tpg->sessions_kobj);
+	kobject_put(se_tpg->sessions_kobj);
+
+	kobject_del(se_tpg->kobj);
+	kobject_put(se_tpg->kobj);
+
 	configfs_remove_default_groups(&se_tpg->tpg_group);
 	config_item_put(item);
 }
@@ -927,6 +948,7 @@ static struct config_group *target_fabric_make_wwn(
 	struct target_fabric_configfs *tf = container_of(group,
 				struct target_fabric_configfs, tf_group);
 	struct se_wwn *wwn;
+	int ret;
 
 	if (!tf->tf_ops->fabric_make_wwn) {
 		pr_err("tf->tf_ops.fabric_make_wwn is NULL\n");
@@ -938,6 +960,9 @@ static struct config_group *target_fabric_make_wwn(
 		return ERR_PTR(-EINVAL);
 
 	wwn->wwn_tf = tf;
+	wwn->kobj = kobject_create_and_add(name, tf->kobj);
+	if (!wwn->kobj)
+		goto drop_wwn;
 
 	config_group_init_type_name(&wwn->wwn_group, name, &tf->tf_tpg_cit);
 
@@ -947,7 +972,12 @@ static struct config_group *target_fabric_make_wwn(
 
 	if (tf->tf_ops->add_wwn_groups)
 		tf->tf_ops->add_wwn_groups(wwn);
+
 	return &wwn->wwn_group;
+
+drop_wwn:
+	tf->tf_ops->fabric_drop_wwn(wwn);
+	return ERR_PTR(ret);
 }
 
 static void target_fabric_drop_wwn(
@@ -957,6 +987,8 @@ static void target_fabric_drop_wwn(
 	struct se_wwn *wwn = container_of(to_config_group(item),
 				struct se_wwn, wwn_group);
 
+	kobject_del(wwn->kobj);
+	kobject_put(wwn->kobj);
 	configfs_remove_default_groups(&wwn->wwn_group);
 	config_item_put(item);
 }
diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h
index efc5449..d242a97 100644
--- a/drivers/target/target_core_internal.h
+++ b/drivers/target/target_core_internal.h
@@ -27,6 +27,7 @@ struct target_backend {
 struct target_fabric_configfs {
 	atomic_t		tf_access_cnt;
 	struct list_head	tf_list;
+	struct kobject		*kobj;
 	struct config_group	tf_group;
 	struct config_group	tf_disc_group;
 	const struct target_core_fabric_ops *tf_ops;
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index cd440ea..b48f8cf 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -8,6 +8,7 @@
 #include <linux/percpu-refcount.h>
 #include <linux/semaphore.h>     /* struct semaphore */
 #include <linux/completion.h>
+#include <linux/kobject.h>
 
 #define TARGET_CORE_VERSION		"v5.0"
 
@@ -909,6 +910,8 @@ struct se_portal_group {
 	/* Pointer to $FABRIC_MOD dependent code */
 	const struct target_core_fabric_ops *se_tpg_tfo;
 	struct se_wwn		*se_tpg_wwn;
+	struct kobject		*kobj;
+	struct kobject		*sessions_kobj;
 	struct config_group	tpg_group;
 	struct config_group	tpg_lun_group;
 	struct config_group	tpg_np_group;
@@ -947,6 +950,7 @@ struct se_wwn {
 	void			*priv;
 	struct config_group	wwn_group;
 	struct config_group	fabric_stat_group;
+	struct kobject		*kobj;
 };
 
 static inline void atomic_inc_mb(atomic_t *v)
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [RFC PATCH 08/12] target: add sysfs session helper functions
  2020-04-20 19:14 ` Mike Christie
@ 2020-04-20 19:14   ` Mike Christie
  -1 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel
  Cc: Mike Christie

This patch adds helpers to add/remove a dir per session. There is
only 2 files/dirs.

acl - name of acl session is accessed through.
transport_id - Contains fabric module specific transportID values.

iSCSI example:

scsi_target/
├── iscsi
│   └── iqn.1999-09.com.tcmu:alua
│       ├── tpgt_1
│       │   └── sessions
│       │       └── session-1
│       │           ├── acl
│       │           └── transport_id
│       │               ├── format
│       │               ├── iscsi_name
│       │               ├── iscsi_session_id
│       │               └── proto
│       └── tpgt_2
│           └── sessions
.....

Fabric drivers like iscsi or elx can add pass in an attribute_group
to add driver specific attrs via the target_core_fabric_ops
session_attrs field.

Note that this adds back the global sid allocator instead of the per tpg
one because in the future we will want to tag target_core_user commands
with the session id. This will be needed when tcmu devices are mapped
to multiple fabric modules or tpgs and they userspace needs to track
the different session to command mappings for commands like PRs.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
V2:
- Fix extra newline
- Copy data that's exported to sysfs so we do not have to worry about
configfs and sysfs refcounts.

 drivers/target/Makefile                |   1 +
 drivers/target/target_core_internal.h  |   4 +
 drivers/target/target_core_sysfs.c     | 296 +++++++++++++++++++++++++++++++++
 drivers/target/target_core_transport.c |  43 ++++-
 include/target/target_core_base.h      |   6 +
 include/target/target_core_fabric.h    |   8 +-
 6 files changed, 351 insertions(+), 7 deletions(-)
 create mode 100644 drivers/target/target_core_sysfs.c

diff --git a/drivers/target/Makefile b/drivers/target/Makefile
index 4563474..4a7246e 100644
--- a/drivers/target/Makefile
+++ b/drivers/target/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 
 target_core_mod-y		:= target_core_configfs.o \
+				   target_core_sysfs.o \
 				   target_core_device.o \
 				   target_core_fabric_configfs.o \
 				   target_core_fabric_lib.o \
diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h
index d242a97..c85eb30 100644
--- a/drivers/target/target_core_internal.h
+++ b/drivers/target/target_core_internal.h
@@ -108,6 +108,9 @@ const char *target_parse_pr_out_transport_id(struct se_portal_group *tpg,
 void target_free_transport_id(struct t10_transport_id *tpid);
 char *transport_id_get_sid(struct t10_transport_id *tpid);
 
+/* target_core_sysfs.c */
+void	target_sysfs_init_session(struct se_session *sess);
+
 /* target_core_hba.c */
 struct se_hba *core_alloc_hba(const char *, u32, u32);
 int	core_delete_hba(struct se_hba *);
@@ -155,6 +158,7 @@ void	transport_dump_dev_info(struct se_device *, struct se_lun *,
 bool	target_check_wce(struct se_device *dev);
 bool	target_check_fua(struct se_device *dev);
 void	__target_execute_cmd(struct se_cmd *, bool);
+void	__target_free_session(struct se_session *);
 
 /* target_core_stat.c */
 void	target_stat_setup_dev_default_groups(struct se_device *);
diff --git a/drivers/target/target_core_sysfs.c b/drivers/target/target_core_sysfs.c
new file mode 100644
index 0000000..d8f2c1e
--- /dev/null
+++ b/drivers/target/target_core_sysfs.c
@@ -0,0 +1,296 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/kobject.h>
+#include <linux/idr.h>
+
+#include <scsi/scsi_proto.h>
+
+#include <target/target_core_base.h>
+#include <target/target_core_fabric.h>
+#include "target_core_internal.h"
+
+static void target_sysfs_session_release(struct kobject *kobj)
+{
+	struct se_session *se_sess = container_of(kobj, struct se_session, kobj);
+
+	__target_free_session(se_sess);
+}
+
+struct session_attr {
+	struct attribute attr;
+	ssize_t (*show)(struct se_session *, char *);
+	ssize_t (*store)(struct se_session *, const char *, size_t);
+};
+
+#define to_session(atr) container_of((atr), struct session_attr, attr)
+
+static ssize_t session_acl_show(struct se_session *se_sess, char *page)
+{
+	return snprintf(page, PAGE_SIZE, "%s\n", se_sess->acl_name ?
+			se_sess->acl_name : "");
+}
+
+static struct session_attr session_acl_attr = {
+	.attr = { .name = "acl", .mode = S_IRUGO },
+	.show = session_acl_show,
+};
+
+/* Default attrs common to all fabric modules */
+static struct attribute *session_attrs[] = {
+	&session_acl_attr.attr,
+	NULL
+};
+ATTRIBUTE_GROUPS(session);
+
+/* transportID attrs */
+#define transport_id_def_attr_show(name, fmt_str)		\
+static ssize_t def_show_##name(struct se_session *se_sess, char *page) \
+{									\
+	return snprintf(page, PAGE_SIZE, fmt_str, se_sess->tpid->name); \
+}
+
+#define transport_id_def_attr(name, fmt_str)		\
+	transport_id_def_attr_show(name, fmt_str)		\
+static struct session_attr transport_id_def_##name##_attr =	\
+	__ATTR(name, S_IRUGO, def_show_##name, NULL)
+
+#define transport_id_attr_show(pref, name, fmt_str)			\
+static ssize_t show_##pref##_##name(struct se_session *se_sess, char *page) \
+{									\
+	return snprintf(page, PAGE_SIZE, fmt_str, se_sess->tpid->pref.name); \
+}
+
+#define transport_id_attr(pref, name, fmt_str)				\
+	transport_id_attr_show(pref, name, fmt_str)			\
+static struct session_attr transport_id_##pref##_##name##_attr =	\
+	__ATTR(name, S_IRUGO, show_##pref##_##name, NULL)
+
+transport_id_def_attr(proto, "%u\n");
+transport_id_def_attr(format, "%u\n");
+transport_id_attr(fcp, port_name, "%s\n");
+transport_id_attr(sbp, name, "%s\n");
+transport_id_attr(srp, port_id, "%s\n");
+transport_id_attr(sas, addr, "%s\n");
+transport_id_attr(iscsi, name, "%s\n");
+transport_id_attr(iscsi, session_id, "%s\n");
+
+static struct attribute *transport_id_fcp_attrs[] = {
+	&transport_id_def_proto_attr.attr,
+	&transport_id_def_format_attr.attr,
+	&transport_id_fcp_port_name_attr.attr,
+	NULL
+};
+
+static struct attribute *transport_id_sbp_attrs[] = {
+	&transport_id_def_proto_attr.attr,
+	&transport_id_def_format_attr.attr,
+	&transport_id_sbp_name_attr.attr,
+	NULL
+};
+
+static struct attribute *transport_id_srp_attrs[] = {
+	&transport_id_def_proto_attr.attr,
+	&transport_id_def_format_attr.attr,
+	&transport_id_srp_port_id_attr.attr,
+	NULL
+};
+
+static struct attribute *transport_id_sas_attrs[] = {
+	&transport_id_def_proto_attr.attr,
+	&transport_id_def_format_attr.attr,
+	&transport_id_sas_addr_attr.attr,
+	NULL
+};
+
+static struct attribute *transport_id_iscsi_attrs[] = {
+	&transport_id_def_proto_attr.attr,
+	&transport_id_def_format_attr.attr,
+	&transport_id_iscsi_name_attr.attr,
+	&transport_id_iscsi_session_id_attr.attr,
+	NULL
+};
+
+static const struct attribute_group transport_id_fcp_attr_group = {
+	.name = "transport_id",
+	.attrs = transport_id_fcp_attrs,
+};
+
+static const struct attribute_group transport_id_sbp_attr_group = {
+	.name = "transport_id",
+	.attrs = transport_id_sbp_attrs,
+};
+
+static const struct attribute_group transport_id_srp_attr_group = {
+	.name = "transport_id",
+	.attrs = transport_id_srp_attrs,
+};
+
+static const struct attribute_group transport_id_sas_attr_group = {
+	.name = "transport_id",
+	.attrs = transport_id_sas_attrs,
+};
+
+static const struct attribute_group transport_id_iscsi_attr_group = {
+	.name = "transport_id",
+	.attrs = transport_id_iscsi_attrs,
+};
+
+static ssize_t
+session_attr_store(struct kobject *kobj, struct attribute *attr,
+		   const char *page, size_t length)
+{
+	struct se_session *se_sess = container_of(kobj, struct se_session, kobj);
+	struct session_attr *sess_attr = to_session(attr);
+
+	if (!sess_attr->store)
+		return -ENOSYS;
+
+	return sess_attr->store(se_sess, page, length);
+}
+
+static ssize_t
+session_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
+{
+	struct se_session *se_sess = container_of(kobj, struct se_session, kobj);
+	struct session_attr *sess_attr = to_session(attr);
+
+	if (!sess_attr->show)
+		return -ENOSYS;
+
+	return sess_attr->show(se_sess, page);
+}
+
+static const struct sysfs_ops session_sysfs_ops = {
+	.show	= session_attr_show,
+	.store	= session_attr_store,
+};
+
+static struct kobj_type session_ktype = {
+	.sysfs_ops	= &session_sysfs_ops,
+	.release	= target_sysfs_session_release,
+	.default_groups	= session_groups,
+};
+
+void target_sysfs_init_session(struct se_session *se_sess)
+{
+	kobject_init(&se_sess->kobj, &session_ktype);
+}
+
+static int add_transport_id_attrs(struct se_session *se_sess)
+{
+	int ret = 0;
+
+	switch (se_sess->tpid->proto) {
+
+	case SCSI_PROTOCOL_FCP:
+		ret = sysfs_create_group(&se_sess->kobj,
+					 &transport_id_fcp_attr_group);
+		break;
+	case SCSI_PROTOCOL_SBP:
+		ret = sysfs_create_group(&se_sess->kobj,
+					 &transport_id_sbp_attr_group);
+		break;
+	case SCSI_PROTOCOL_SRP:
+		ret = sysfs_create_group(&se_sess->kobj,
+					 &transport_id_srp_attr_group);
+		break;
+	case SCSI_PROTOCOL_SAS:
+		ret = sysfs_create_group(&se_sess->kobj,
+					 &transport_id_sas_attr_group);
+		break;
+	case SCSI_PROTOCOL_ISCSI:
+		ret = sysfs_create_group(&se_sess->kobj,
+					 &transport_id_iscsi_attr_group);
+		break;
+	}
+
+	return ret;
+}
+
+static void remove_transport_id_attrs(struct se_session *se_sess)
+{
+	switch (se_sess->tpid->proto) {
+	case SCSI_PROTOCOL_FCP:
+		sysfs_remove_group(&se_sess->kobj,
+				   &transport_id_fcp_attr_group);
+		break;
+	case SCSI_PROTOCOL_SBP:
+		sysfs_remove_group(&se_sess->kobj,
+				   &transport_id_sbp_attr_group);
+		break;
+	case SCSI_PROTOCOL_SRP:
+		sysfs_remove_group(&se_sess->kobj,
+				   &transport_id_srp_attr_group);
+		break;
+	case SCSI_PROTOCOL_SAS:
+		sysfs_remove_group(&se_sess->kobj,
+				   &transport_id_sas_attr_group);
+		break;
+	case SCSI_PROTOCOL_ISCSI:
+		sysfs_remove_group(&se_sess->kobj,
+				   &transport_id_iscsi_attr_group);
+		break;
+	}
+}
+
+int target_sysfs_add_session(struct se_portal_group *se_tpg,
+			     struct se_session *se_sess)
+{
+	int ret;
+
+	/*
+	 * Copy ACL name so we don't have to worry about mixing configfs
+	 * and sysfs refcounts.
+	 */
+	if (!se_sess->se_node_acl->dynamic_node_acl) {
+		se_sess->acl_name = kstrdup(se_sess->se_node_acl->initiatorname,
+					    GFP_KERNEL);
+		if (!se_sess->acl_name)
+			return -ENOMEM;
+	}
+
+	ret = kobject_add(&se_sess->kobj, se_tpg->sessions_kobj, "session-%d",
+			  se_sess->sid);
+	if (ret) {
+		pr_err("Could not add session%d to sysfs. Error %d.\n",
+		       se_sess->sid, ret);
+		goto free_acl_name;
+	}
+
+	ret = add_transport_id_attrs(se_sess);
+	if (ret)
+		goto del_kobj;
+
+	if (se_sess->tfo->session_attrs) {
+		ret = sysfs_create_group(&se_sess->kobj,
+					 se_sess->tfo->session_attrs);
+		if (ret)
+			goto rm_tpid_grps;
+	}
+	se_sess->sysfs_added = true;
+
+	return 0;
+
+rm_tpid_grps:
+	remove_transport_id_attrs(se_sess);
+del_kobj:
+	kobject_del(&se_sess->kobj);
+free_acl_name:
+	kfree(se_sess->acl_name);
+	se_sess->acl_name = NULL;
+	return ret;
+}
+EXPORT_SYMBOL(target_sysfs_add_session);
+
+void target_sysfs_remove_session(struct se_session *se_sess)
+{
+	/* discovery sessions are normally not added to sysfs */
+	if (!se_sess->sysfs_added)
+		return;
+
+	remove_transport_id_attrs(se_sess);
+
+	if (se_sess->tfo->session_attrs)
+		sysfs_remove_group(&se_sess->kobj, se_sess->tfo->session_attrs);
+	kobject_del(&se_sess->kobj);
+}
+EXPORT_SYMBOL(target_sysfs_remove_session);
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 66f0af1..d3248d4 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -42,6 +42,8 @@
 
 static struct workqueue_struct *target_completion_wq;
 static struct kmem_cache *se_sess_cache;
+static DEFINE_MUTEX(se_sess_idr_mutex);
+static DEFINE_IDR(se_sess_idr);
 struct kmem_cache *se_ua_cache;
 struct kmem_cache *t10_pr_reg_cache;
 struct kmem_cache *t10_alua_lu_gp_cache;
@@ -251,14 +253,32 @@ struct se_session *transport_alloc_session(enum target_prot_op sup_prot_ops)
 				" se_sess_cache\n");
 		return ERR_PTR(-ENOMEM);
 	}
-	ret = transport_init_session(se_sess);
+
+	mutex_lock(&se_sess_idr_mutex);
+	ret = idr_alloc_cyclic(&se_sess_idr, NULL, 1, 0, GFP_KERNEL);
+	if (ret >= 0)
+		se_sess->sid = ret;
+	mutex_unlock(&se_sess_idr_mutex);
 	if (ret < 0) {
-		kmem_cache_free(se_sess_cache, se_sess);
-		return ERR_PTR(ret);
+		pr_err("Unable to allocate session index.\n");
+		goto free_sess;
 	}
-	se_sess->sup_prot_ops = sup_prot_ops;
 
+	ret = transport_init_session(se_sess);
+	if (ret < 0)
+		goto free_sid;
+
+	se_sess->sup_prot_ops = sup_prot_ops;
+	target_sysfs_init_session(se_sess);
 	return se_sess;
+
+free_sid:
+	mutex_lock(&se_sess_idr_mutex);
+	idr_remove(&se_sess_idr, se_sess->sid);
+	mutex_unlock(&se_sess_idr_mutex);
+free_sess:
+	kmem_cache_free(se_sess_cache, se_sess);
+	return ERR_PTR(ret);
 }
 EXPORT_SYMBOL(transport_alloc_session);
 
@@ -585,12 +605,23 @@ void transport_free_session(struct se_session *se_sess)
 		sbitmap_queue_free(&se_sess->sess_tag_pool);
 		kvfree(se_sess->sess_cmd_map);
 	}
-	target_free_transport_id(se_sess->tpid);
 	percpu_ref_exit(&se_sess->cmd_count);
-	kmem_cache_free(se_sess_cache, se_sess);
+	kobject_put(&se_sess->kobj);
 }
 EXPORT_SYMBOL(transport_free_session);
 
+void __target_free_session(struct se_session *se_sess)
+{
+	kfree(se_sess->acl_name);
+	target_free_transport_id(se_sess->tpid);
+
+	mutex_lock(&se_sess_idr_mutex);
+	idr_remove(&se_sess_idr, se_sess->sid);
+	mutex_unlock(&se_sess_idr_mutex);
+
+	kmem_cache_free(se_sess_cache, se_sess);
+}
+
 static int target_release_res(struct se_device *dev, void *data)
 {
 	struct se_session *sess = data;
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index b48f8cf..61115b7 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -9,6 +9,7 @@
 #include <linux/semaphore.h>     /* struct semaphore */
 #include <linux/completion.h>
 #include <linux/kobject.h>
+#include <linux/idr.h>
 
 #define TARGET_CORE_VERSION		"v5.0"
 
@@ -633,6 +634,7 @@ struct se_session {
 	enum target_prot_op	sup_prot_ops;
 	enum target_prot_type	sess_prot_type;
 	struct se_node_acl	*se_node_acl;
+	char			*acl_name;
 	struct se_portal_group *se_tpg;
 	void			*fabric_sess_ptr;
 	struct percpu_ref	cmd_count;
@@ -643,6 +645,10 @@ struct se_session {
 	wait_queue_head_t	cmd_list_wq;
 	void			*sess_cmd_map;
 	struct sbitmap_queue	sess_tag_pool;
+	struct kobject		kobj;
+	int			sid;
+	bool			sysfs_added;
+	const struct target_core_fabric_ops *tfo;
 };
 
 struct se_device;
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
index 0c1720d..be43180 100644
--- a/include/target/target_core_fabric.h
+++ b/include/target/target_core_fabric.h
@@ -74,6 +74,10 @@ struct target_core_fabric_ops {
 	int (*queue_status)(struct se_cmd *);
 	void (*queue_tm_rsp)(struct se_cmd *);
 	void (*aborted_task)(struct se_cmd *);
+
+	/* Optional session management and sysfs callouts */
+	const struct attribute_group *session_attrs;
+
 	/*
 	 * fabric module calls for target_core_fabric_configfs.c
 	 */
@@ -141,7 +145,9 @@ void	transport_register_session(struct se_portal_group *,
 void	target_put_nacl(struct se_node_acl *);
 void	transport_deregister_session_configfs(struct se_session *);
 void	transport_deregister_session(struct se_session *);
-
+void	target_sysfs_remove_session(struct se_session *se_sess);
+int	target_sysfs_add_session(struct se_portal_group *se_tpg,
+				 struct se_session *se_sess);
 
 void	transport_init_se_cmd(struct se_cmd *,
 		const struct target_core_fabric_ops *,
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [RFC PATCH 08/12] target: add sysfs session helper functions
@ 2020-04-20 19:14   ` Mike Christie
  0 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel
  Cc: Mike Christie

This patch adds helpers to add/remove a dir per session. There is
only 2 files/dirs.

acl - name of acl session is accessed through.
transport_id - Contains fabric module specific transportID values.

iSCSI example:

scsi_target/
├── iscsi
│   └── iqn.1999-09.com.tcmu:alua
│       ├── tpgt_1
│       │   └── sessions
│       │       └── session-1
│       │           ├── acl
│       │           └── transport_id
│       │               ├── format
│       │               ├── iscsi_name
│       │               ├── iscsi_session_id
│       │               └── proto
│       └── tpgt_2
│           └── sessions
.....

Fabric drivers like iscsi or elx can add pass in an attribute_group
to add driver specific attrs via the target_core_fabric_ops
session_attrs field.

Note that this adds back the global sid allocator instead of the per tpg
one because in the future we will want to tag target_core_user commands
with the session id. This will be needed when tcmu devices are mapped
to multiple fabric modules or tpgs and they userspace needs to track
the different session to command mappings for commands like PRs.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
V2:
- Fix extra newline
- Copy data that's exported to sysfs so we do not have to worry about
configfs and sysfs refcounts.

 drivers/target/Makefile                |   1 +
 drivers/target/target_core_internal.h  |   4 +
 drivers/target/target_core_sysfs.c     | 296 +++++++++++++++++++++++++++++++++
 drivers/target/target_core_transport.c |  43 ++++-
 include/target/target_core_base.h      |   6 +
 include/target/target_core_fabric.h    |   8 +-
 6 files changed, 351 insertions(+), 7 deletions(-)
 create mode 100644 drivers/target/target_core_sysfs.c

diff --git a/drivers/target/Makefile b/drivers/target/Makefile
index 4563474..4a7246e 100644
--- a/drivers/target/Makefile
+++ b/drivers/target/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 
 target_core_mod-y		:= target_core_configfs.o \
+				   target_core_sysfs.o \
 				   target_core_device.o \
 				   target_core_fabric_configfs.o \
 				   target_core_fabric_lib.o \
diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h
index d242a97..c85eb30 100644
--- a/drivers/target/target_core_internal.h
+++ b/drivers/target/target_core_internal.h
@@ -108,6 +108,9 @@ const char *target_parse_pr_out_transport_id(struct se_portal_group *tpg,
 void target_free_transport_id(struct t10_transport_id *tpid);
 char *transport_id_get_sid(struct t10_transport_id *tpid);
 
+/* target_core_sysfs.c */
+void	target_sysfs_init_session(struct se_session *sess);
+
 /* target_core_hba.c */
 struct se_hba *core_alloc_hba(const char *, u32, u32);
 int	core_delete_hba(struct se_hba *);
@@ -155,6 +158,7 @@ void	transport_dump_dev_info(struct se_device *, struct se_lun *,
 bool	target_check_wce(struct se_device *dev);
 bool	target_check_fua(struct se_device *dev);
 void	__target_execute_cmd(struct se_cmd *, bool);
+void	__target_free_session(struct se_session *);
 
 /* target_core_stat.c */
 void	target_stat_setup_dev_default_groups(struct se_device *);
diff --git a/drivers/target/target_core_sysfs.c b/drivers/target/target_core_sysfs.c
new file mode 100644
index 0000000..d8f2c1e
--- /dev/null
+++ b/drivers/target/target_core_sysfs.c
@@ -0,0 +1,296 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/kobject.h>
+#include <linux/idr.h>
+
+#include <scsi/scsi_proto.h>
+
+#include <target/target_core_base.h>
+#include <target/target_core_fabric.h>
+#include "target_core_internal.h"
+
+static void target_sysfs_session_release(struct kobject *kobj)
+{
+	struct se_session *se_sess = container_of(kobj, struct se_session, kobj);
+
+	__target_free_session(se_sess);
+}
+
+struct session_attr {
+	struct attribute attr;
+	ssize_t (*show)(struct se_session *, char *);
+	ssize_t (*store)(struct se_session *, const char *, size_t);
+};
+
+#define to_session(atr) container_of((atr), struct session_attr, attr)
+
+static ssize_t session_acl_show(struct se_session *se_sess, char *page)
+{
+	return snprintf(page, PAGE_SIZE, "%s\n", se_sess->acl_name ?
+			se_sess->acl_name : "");
+}
+
+static struct session_attr session_acl_attr = {
+	.attr = { .name = "acl", .mode = S_IRUGO },
+	.show = session_acl_show,
+};
+
+/* Default attrs common to all fabric modules */
+static struct attribute *session_attrs[] = {
+	&session_acl_attr.attr,
+	NULL
+};
+ATTRIBUTE_GROUPS(session);
+
+/* transportID attrs */
+#define transport_id_def_attr_show(name, fmt_str)		\
+static ssize_t def_show_##name(struct se_session *se_sess, char *page) \
+{									\
+	return snprintf(page, PAGE_SIZE, fmt_str, se_sess->tpid->name); \
+}
+
+#define transport_id_def_attr(name, fmt_str)		\
+	transport_id_def_attr_show(name, fmt_str)		\
+static struct session_attr transport_id_def_##name##_attr =	\
+	__ATTR(name, S_IRUGO, def_show_##name, NULL)
+
+#define transport_id_attr_show(pref, name, fmt_str)			\
+static ssize_t show_##pref##_##name(struct se_session *se_sess, char *page) \
+{									\
+	return snprintf(page, PAGE_SIZE, fmt_str, se_sess->tpid->pref.name); \
+}
+
+#define transport_id_attr(pref, name, fmt_str)				\
+	transport_id_attr_show(pref, name, fmt_str)			\
+static struct session_attr transport_id_##pref##_##name##_attr =	\
+	__ATTR(name, S_IRUGO, show_##pref##_##name, NULL)
+
+transport_id_def_attr(proto, "%u\n");
+transport_id_def_attr(format, "%u\n");
+transport_id_attr(fcp, port_name, "%s\n");
+transport_id_attr(sbp, name, "%s\n");
+transport_id_attr(srp, port_id, "%s\n");
+transport_id_attr(sas, addr, "%s\n");
+transport_id_attr(iscsi, name, "%s\n");
+transport_id_attr(iscsi, session_id, "%s\n");
+
+static struct attribute *transport_id_fcp_attrs[] = {
+	&transport_id_def_proto_attr.attr,
+	&transport_id_def_format_attr.attr,
+	&transport_id_fcp_port_name_attr.attr,
+	NULL
+};
+
+static struct attribute *transport_id_sbp_attrs[] = {
+	&transport_id_def_proto_attr.attr,
+	&transport_id_def_format_attr.attr,
+	&transport_id_sbp_name_attr.attr,
+	NULL
+};
+
+static struct attribute *transport_id_srp_attrs[] = {
+	&transport_id_def_proto_attr.attr,
+	&transport_id_def_format_attr.attr,
+	&transport_id_srp_port_id_attr.attr,
+	NULL
+};
+
+static struct attribute *transport_id_sas_attrs[] = {
+	&transport_id_def_proto_attr.attr,
+	&transport_id_def_format_attr.attr,
+	&transport_id_sas_addr_attr.attr,
+	NULL
+};
+
+static struct attribute *transport_id_iscsi_attrs[] = {
+	&transport_id_def_proto_attr.attr,
+	&transport_id_def_format_attr.attr,
+	&transport_id_iscsi_name_attr.attr,
+	&transport_id_iscsi_session_id_attr.attr,
+	NULL
+};
+
+static const struct attribute_group transport_id_fcp_attr_group = {
+	.name = "transport_id",
+	.attrs = transport_id_fcp_attrs,
+};
+
+static const struct attribute_group transport_id_sbp_attr_group = {
+	.name = "transport_id",
+	.attrs = transport_id_sbp_attrs,
+};
+
+static const struct attribute_group transport_id_srp_attr_group = {
+	.name = "transport_id",
+	.attrs = transport_id_srp_attrs,
+};
+
+static const struct attribute_group transport_id_sas_attr_group = {
+	.name = "transport_id",
+	.attrs = transport_id_sas_attrs,
+};
+
+static const struct attribute_group transport_id_iscsi_attr_group = {
+	.name = "transport_id",
+	.attrs = transport_id_iscsi_attrs,
+};
+
+static ssize_t
+session_attr_store(struct kobject *kobj, struct attribute *attr,
+		   const char *page, size_t length)
+{
+	struct se_session *se_sess = container_of(kobj, struct se_session, kobj);
+	struct session_attr *sess_attr = to_session(attr);
+
+	if (!sess_attr->store)
+		return -ENOSYS;
+
+	return sess_attr->store(se_sess, page, length);
+}
+
+static ssize_t
+session_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
+{
+	struct se_session *se_sess = container_of(kobj, struct se_session, kobj);
+	struct session_attr *sess_attr = to_session(attr);
+
+	if (!sess_attr->show)
+		return -ENOSYS;
+
+	return sess_attr->show(se_sess, page);
+}
+
+static const struct sysfs_ops session_sysfs_ops = {
+	.show	= session_attr_show,
+	.store	= session_attr_store,
+};
+
+static struct kobj_type session_ktype = {
+	.sysfs_ops	= &session_sysfs_ops,
+	.release	= target_sysfs_session_release,
+	.default_groups	= session_groups,
+};
+
+void target_sysfs_init_session(struct se_session *se_sess)
+{
+	kobject_init(&se_sess->kobj, &session_ktype);
+}
+
+static int add_transport_id_attrs(struct se_session *se_sess)
+{
+	int ret = 0;
+
+	switch (se_sess->tpid->proto) {
+
+	case SCSI_PROTOCOL_FCP:
+		ret = sysfs_create_group(&se_sess->kobj,
+					 &transport_id_fcp_attr_group);
+		break;
+	case SCSI_PROTOCOL_SBP:
+		ret = sysfs_create_group(&se_sess->kobj,
+					 &transport_id_sbp_attr_group);
+		break;
+	case SCSI_PROTOCOL_SRP:
+		ret = sysfs_create_group(&se_sess->kobj,
+					 &transport_id_srp_attr_group);
+		break;
+	case SCSI_PROTOCOL_SAS:
+		ret = sysfs_create_group(&se_sess->kobj,
+					 &transport_id_sas_attr_group);
+		break;
+	case SCSI_PROTOCOL_ISCSI:
+		ret = sysfs_create_group(&se_sess->kobj,
+					 &transport_id_iscsi_attr_group);
+		break;
+	}
+
+	return ret;
+}
+
+static void remove_transport_id_attrs(struct se_session *se_sess)
+{
+	switch (se_sess->tpid->proto) {
+	case SCSI_PROTOCOL_FCP:
+		sysfs_remove_group(&se_sess->kobj,
+				   &transport_id_fcp_attr_group);
+		break;
+	case SCSI_PROTOCOL_SBP:
+		sysfs_remove_group(&se_sess->kobj,
+				   &transport_id_sbp_attr_group);
+		break;
+	case SCSI_PROTOCOL_SRP:
+		sysfs_remove_group(&se_sess->kobj,
+				   &transport_id_srp_attr_group);
+		break;
+	case SCSI_PROTOCOL_SAS:
+		sysfs_remove_group(&se_sess->kobj,
+				   &transport_id_sas_attr_group);
+		break;
+	case SCSI_PROTOCOL_ISCSI:
+		sysfs_remove_group(&se_sess->kobj,
+				   &transport_id_iscsi_attr_group);
+		break;
+	}
+}
+
+int target_sysfs_add_session(struct se_portal_group *se_tpg,
+			     struct se_session *se_sess)
+{
+	int ret;
+
+	/*
+	 * Copy ACL name so we don't have to worry about mixing configfs
+	 * and sysfs refcounts.
+	 */
+	if (!se_sess->se_node_acl->dynamic_node_acl) {
+		se_sess->acl_name = kstrdup(se_sess->se_node_acl->initiatorname,
+					    GFP_KERNEL);
+		if (!se_sess->acl_name)
+			return -ENOMEM;
+	}
+
+	ret = kobject_add(&se_sess->kobj, se_tpg->sessions_kobj, "session-%d",
+			  se_sess->sid);
+	if (ret) {
+		pr_err("Could not add session%d to sysfs. Error %d.\n",
+		       se_sess->sid, ret);
+		goto free_acl_name;
+	}
+
+	ret = add_transport_id_attrs(se_sess);
+	if (ret)
+		goto del_kobj;
+
+	if (se_sess->tfo->session_attrs) {
+		ret = sysfs_create_group(&se_sess->kobj,
+					 se_sess->tfo->session_attrs);
+		if (ret)
+			goto rm_tpid_grps;
+	}
+	se_sess->sysfs_added = true;
+
+	return 0;
+
+rm_tpid_grps:
+	remove_transport_id_attrs(se_sess);
+del_kobj:
+	kobject_del(&se_sess->kobj);
+free_acl_name:
+	kfree(se_sess->acl_name);
+	se_sess->acl_name = NULL;
+	return ret;
+}
+EXPORT_SYMBOL(target_sysfs_add_session);
+
+void target_sysfs_remove_session(struct se_session *se_sess)
+{
+	/* discovery sessions are normally not added to sysfs */
+	if (!se_sess->sysfs_added)
+		return;
+
+	remove_transport_id_attrs(se_sess);
+
+	if (se_sess->tfo->session_attrs)
+		sysfs_remove_group(&se_sess->kobj, se_sess->tfo->session_attrs);
+	kobject_del(&se_sess->kobj);
+}
+EXPORT_SYMBOL(target_sysfs_remove_session);
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 66f0af1..d3248d4 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -42,6 +42,8 @@
 
 static struct workqueue_struct *target_completion_wq;
 static struct kmem_cache *se_sess_cache;
+static DEFINE_MUTEX(se_sess_idr_mutex);
+static DEFINE_IDR(se_sess_idr);
 struct kmem_cache *se_ua_cache;
 struct kmem_cache *t10_pr_reg_cache;
 struct kmem_cache *t10_alua_lu_gp_cache;
@@ -251,14 +253,32 @@ struct se_session *transport_alloc_session(enum target_prot_op sup_prot_ops)
 				" se_sess_cache\n");
 		return ERR_PTR(-ENOMEM);
 	}
-	ret = transport_init_session(se_sess);
+
+	mutex_lock(&se_sess_idr_mutex);
+	ret = idr_alloc_cyclic(&se_sess_idr, NULL, 1, 0, GFP_KERNEL);
+	if (ret >= 0)
+		se_sess->sid = ret;
+	mutex_unlock(&se_sess_idr_mutex);
 	if (ret < 0) {
-		kmem_cache_free(se_sess_cache, se_sess);
-		return ERR_PTR(ret);
+		pr_err("Unable to allocate session index.\n");
+		goto free_sess;
 	}
-	se_sess->sup_prot_ops = sup_prot_ops;
 
+	ret = transport_init_session(se_sess);
+	if (ret < 0)
+		goto free_sid;
+
+	se_sess->sup_prot_ops = sup_prot_ops;
+	target_sysfs_init_session(se_sess);
 	return se_sess;
+
+free_sid:
+	mutex_lock(&se_sess_idr_mutex);
+	idr_remove(&se_sess_idr, se_sess->sid);
+	mutex_unlock(&se_sess_idr_mutex);
+free_sess:
+	kmem_cache_free(se_sess_cache, se_sess);
+	return ERR_PTR(ret);
 }
 EXPORT_SYMBOL(transport_alloc_session);
 
@@ -585,12 +605,23 @@ void transport_free_session(struct se_session *se_sess)
 		sbitmap_queue_free(&se_sess->sess_tag_pool);
 		kvfree(se_sess->sess_cmd_map);
 	}
-	target_free_transport_id(se_sess->tpid);
 	percpu_ref_exit(&se_sess->cmd_count);
-	kmem_cache_free(se_sess_cache, se_sess);
+	kobject_put(&se_sess->kobj);
 }
 EXPORT_SYMBOL(transport_free_session);
 
+void __target_free_session(struct se_session *se_sess)
+{
+	kfree(se_sess->acl_name);
+	target_free_transport_id(se_sess->tpid);
+
+	mutex_lock(&se_sess_idr_mutex);
+	idr_remove(&se_sess_idr, se_sess->sid);
+	mutex_unlock(&se_sess_idr_mutex);
+
+	kmem_cache_free(se_sess_cache, se_sess);
+}
+
 static int target_release_res(struct se_device *dev, void *data)
 {
 	struct se_session *sess = data;
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index b48f8cf..61115b7 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -9,6 +9,7 @@
 #include <linux/semaphore.h>     /* struct semaphore */
 #include <linux/completion.h>
 #include <linux/kobject.h>
+#include <linux/idr.h>
 
 #define TARGET_CORE_VERSION		"v5.0"
 
@@ -633,6 +634,7 @@ struct se_session {
 	enum target_prot_op	sup_prot_ops;
 	enum target_prot_type	sess_prot_type;
 	struct se_node_acl	*se_node_acl;
+	char			*acl_name;
 	struct se_portal_group *se_tpg;
 	void			*fabric_sess_ptr;
 	struct percpu_ref	cmd_count;
@@ -643,6 +645,10 @@ struct se_session {
 	wait_queue_head_t	cmd_list_wq;
 	void			*sess_cmd_map;
 	struct sbitmap_queue	sess_tag_pool;
+	struct kobject		kobj;
+	int			sid;
+	bool			sysfs_added;
+	const struct target_core_fabric_ops *tfo;
 };
 
 struct se_device;
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
index 0c1720d..be43180 100644
--- a/include/target/target_core_fabric.h
+++ b/include/target/target_core_fabric.h
@@ -74,6 +74,10 @@ struct target_core_fabric_ops {
 	int (*queue_status)(struct se_cmd *);
 	void (*queue_tm_rsp)(struct se_cmd *);
 	void (*aborted_task)(struct se_cmd *);
+
+	/* Optional session management and sysfs callouts */
+	const struct attribute_group *session_attrs;
+
 	/*
 	 * fabric module calls for target_core_fabric_configfs.c
 	 */
@@ -141,7 +145,9 @@ void	transport_register_session(struct se_portal_group *,
 void	target_put_nacl(struct se_node_acl *);
 void	transport_deregister_session_configfs(struct se_session *);
 void	transport_deregister_session(struct se_session *);
-
+void	target_sysfs_remove_session(struct se_session *se_sess);
+int	target_sysfs_add_session(struct se_portal_group *se_tpg,
+				 struct se_session *se_sess);
 
 void	transport_init_se_cmd(struct se_cmd *,
 		const struct target_core_fabric_ops *,
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [RFC PATCH 09/12] target: move session setup cb to fabric ops
  2020-04-20 19:14 ` Mike Christie
@ 2020-04-20 19:14   ` Mike Christie
  -1 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel
  Cc: Mike Christie

This moves the target_setup_session callback to the fabric ops. It also
adds a new session callback called when the session is freed. This will
be useful in the next patch for fabric mods that add session_attrs
and so we can cleanup from failures in target_setup_session.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 drivers/infiniband/ulp/srpt/ib_srpt.c    |  6 +++---
 drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c |  2 +-
 drivers/scsi/qla2xxx/tcm_qla2xxx.c       |  8 +++++---
 drivers/target/loopback/tcm_loop.c       |  8 ++++----
 drivers/target/sbp/sbp_target.c          |  2 +-
 drivers/target/target_core_transport.c   | 11 ++++++-----
 drivers/target/tcm_fc/tcm_fc.h           |  2 ++
 drivers/target/tcm_fc/tfc_conf.c         |  1 +
 drivers/target/tcm_fc/tfc_sess.c         |  7 +++----
 drivers/usb/gadget/function/f_tcm.c      |  8 ++++----
 drivers/vhost/scsi.c                     |  8 ++++----
 drivers/xen/xen-scsiback.c               |  8 ++++----
 include/target/target_core_fabric.h      |  7 ++++---
 13 files changed, 42 insertions(+), 36 deletions(-)

diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
index 4dd2a41..59a6b9b 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -2325,7 +2325,7 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev,
 			break;
 		ch->sess = target_setup_session(&stpg->tpg, tag_num,
 						tag_size, TARGET_PROT_NORMAL,
-						&tpid, ch->sess_name, ch, NULL);
+						&tpid, ch->sess_name, ch);
 	}
 	mutex_unlock(&sport->port_guid_id.mutex);
 
@@ -2335,13 +2335,13 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev,
 			break;
 		ch->sess = target_setup_session(&stpg->tpg, tag_num,
 					tag_size, TARGET_PROT_NORMAL, &tpid,
-					i_port_id, ch, NULL);
+					i_port_id, ch);
 		if (!IS_ERR_OR_NULL(ch->sess))
 			break;
 		/* Retry without leading "0x" */
 		ch->sess = target_setup_session(&stpg->tpg, tag_num,
 						tag_size, TARGET_PROT_NORMAL,
-						&tpid, i_port_id + 2, ch, NULL);
+						&tpid, i_port_id + 2, ch);
 	}
 	mutex_unlock(&sport->port_gid_id.mutex);
 
diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
index dba9ec0..23ffcd8 100644
--- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
+++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
@@ -2229,7 +2229,7 @@ static int ibmvscsis_make_nexus(struct ibmvscsis_tport *tport)
 
 	nexus->se_sess = target_setup_session(&tport->se_tpg, 0, 0,
 					      TARGET_PROT_NORMAL, &tpid, name,
-					      nexus, NULL);
+					      nexus);
 	if (IS_ERR(nexus->se_sess)) {
 		rc = PTR_ERR(nexus->se_sess);
 		goto transport_init_fail;
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index dc1bddd..d864d13 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -1389,8 +1389,8 @@ static void tcm_qla2xxx_free_session(struct fc_port *sess)
 	target_remove_session(se_sess);
 }
 
-static int tcm_qla2xxx_session_cb(struct se_portal_group *se_tpg,
-				  struct se_session *se_sess, void *p)
+static int tcm_qla2xxx_init_session(struct se_portal_group *se_tpg,
+				    struct se_session *se_sess, void *p)
 {
 	struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
 				struct tcm_qla2xxx_tpg, se_tpg);
@@ -1467,7 +1467,7 @@ static int tcm_qla2xxx_check_initiator_node_acl(
 	se_sess = target_setup_session(&tpg->se_tpg, num_tags,
 				       sizeof(struct qla_tgt_cmd),
 				       TARGET_PROT_ALL, &tpid, port_name,
-				       qlat_sess, tcm_qla2xxx_session_cb);
+				       qlat_sess);
 	if (IS_ERR(se_sess))
 		return PTR_ERR(se_sess);
 
@@ -1832,6 +1832,7 @@ static ssize_t tcm_qla2xxx_wwn_version_show(struct config_item *item,
 	.check_stop_free		= tcm_qla2xxx_check_stop_free,
 	.release_cmd			= tcm_qla2xxx_release_cmd,
 	.close_session			= tcm_qla2xxx_close_session,
+	.init_session			= tcm_qla2xxx_init_session,
 	.sess_get_index			= tcm_qla2xxx_sess_get_index,
 	.write_pending			= tcm_qla2xxx_write_pending,
 	.set_default_node_attributes	= tcm_qla2xxx_set_default_node_attrs,
@@ -1871,6 +1872,7 @@ static ssize_t tcm_qla2xxx_wwn_version_show(struct config_item *item,
 	.check_stop_free                = tcm_qla2xxx_check_stop_free,
 	.release_cmd			= tcm_qla2xxx_release_cmd,
 	.close_session			= tcm_qla2xxx_close_session,
+	.init_session			= tcm_qla2xxx_init_session,
 	.sess_get_index			= tcm_qla2xxx_sess_get_index,
 	.write_pending			= tcm_qla2xxx_write_pending,
 	.set_default_node_attributes	= tcm_qla2xxx_set_default_node_attrs,
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index 7593a53..7025b7e 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -713,8 +713,8 @@ static ssize_t tcm_loop_tpg_attrib_fabric_prot_type_store(
 
 /* Start items for tcm_loop_nexus_cit */
 
-static int tcm_loop_alloc_sess_cb(struct se_portal_group *se_tpg,
-				  struct se_session *se_sess, void *p)
+static int tcm_loop_init_sess(struct se_portal_group *se_tpg,
+			      struct se_session *se_sess, void *p)
 {
 	struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
 					struct tcm_loop_tpg, tl_se_tpg);
@@ -761,8 +761,7 @@ static int tcm_loop_make_nexus(
 
 	tl_nexus->se_sess = target_setup_session(&tl_tpg->tl_se_tpg, 0, 0,
 					TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS,
-					&tpid, name, tl_nexus,
-					tcm_loop_alloc_sess_cb);
+					&tpid, name, tl_nexus);
 	if (IS_ERR(tl_nexus->se_sess)) {
 		ret = PTR_ERR(tl_nexus->se_sess);
 		kfree(tl_nexus);
@@ -1165,6 +1164,7 @@ static ssize_t tcm_loop_wwn_version_show(struct config_item *item, char *page)
 	.queue_status			= tcm_loop_queue_status,
 	.queue_tm_rsp			= tcm_loop_queue_tm_rsp,
 	.aborted_task			= tcm_loop_aborted_task,
+	.init_session			= tcm_loop_init_sess,
 	.fabric_make_wwn		= tcm_loop_make_scsi_hba,
 	.fabric_drop_wwn		= tcm_loop_drop_scsi_hba,
 	.fabric_make_tpg		= tcm_loop_make_naa_tpg,
diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c
index 9a3121d..20f8b3b 100644
--- a/drivers/target/sbp/sbp_target.c
+++ b/drivers/target/sbp/sbp_target.c
@@ -204,7 +204,7 @@ static struct sbp_session *sbp_session_create(
 	sess->se_sess = target_setup_session(&tpg->se_tpg, 128,
 					     sizeof(struct sbp_target_request),
 					     TARGET_PROT_NORMAL, &tpid,
-					     guid_str, sess, NULL);
+					     guid_str, sess);
 	if (IS_ERR(sess->se_sess)) {
 		pr_err("failed to init se_session\n");
 		ret = PTR_ERR(sess->se_sess);
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index d3248d4..7aa830e 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -434,9 +434,7 @@ struct se_session *
 target_setup_session(struct se_portal_group *tpg,
 		     unsigned int tag_num, unsigned int tag_size,
 		     enum target_prot_op prot_op, struct t10_transport_id *tpid,
-		     const char *initiatorname, void *private,
-		     int (*callback)(struct se_portal_group *,
-				     struct se_session *, void *))
+		     const char *initiatorname, void *private)
 {
 	struct se_session *sess;
 	int rc;
@@ -469,8 +467,8 @@ struct se_session *
 	 * Go ahead and perform any remaining fabric setup that is
 	 * required before transport_register_session().
 	 */
-	if (callback != NULL) {
-		rc = callback(tpg, sess, private);
+	if (tpg->se_tpg_tfo->init_session) {
+		rc = tpg->se_tpg_tfo->init_session(tpg, sess, private);
 		if (rc)
 			goto free_sess;
 	}
@@ -612,6 +610,9 @@ void transport_free_session(struct se_session *se_sess)
 
 void __target_free_session(struct se_session *se_sess)
 {
+	if (se_sess->tfo && se_sess->tfo->free_session)
+		se_sess->tfo->free_session(se_sess);
+
 	kfree(se_sess->acl_name);
 	target_free_transport_id(se_sess->tpid);
 
diff --git a/drivers/target/tcm_fc/tcm_fc.h b/drivers/target/tcm_fc/tcm_fc.h
index 2ff716d..ce07b3e 100644
--- a/drivers/target/tcm_fc/tcm_fc.h
+++ b/drivers/target/tcm_fc/tcm_fc.h
@@ -129,6 +129,8 @@ struct ft_cmd {
 /*
  * Session ops.
  */
+
+int ft_sess_init(struct se_portal_group *, struct se_session *, void *);
 void ft_sess_put(struct ft_sess *);
 void ft_sess_close(struct se_session *);
 u32 ft_sess_get_index(struct se_session *);
diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c
index 870b7bb..7983554 100644
--- a/drivers/target/tcm_fc/tfc_conf.c
+++ b/drivers/target/tcm_fc/tfc_conf.c
@@ -426,6 +426,7 @@ static u32 ft_tpg_get_inst_index(struct se_portal_group *se_tpg)
 	.check_stop_free =		ft_check_stop_free,
 	.release_cmd =			ft_release_cmd,
 	.close_session =		ft_sess_close,
+	.init_session =			ft_sess_init,
 	.sess_get_index =		ft_sess_get_index,
 	.write_pending =		ft_write_pending,
 	.set_default_node_attributes =	ft_set_default_node_attr,
diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c
index f261756..7357c38 100644
--- a/drivers/target/tcm_fc/tfc_sess.c
+++ b/drivers/target/tcm_fc/tfc_sess.c
@@ -186,8 +186,8 @@ static struct ft_sess *ft_sess_get(struct fc_lport *lport, u32 port_id)
 	return NULL;
 }
 
-static int ft_sess_alloc_cb(struct se_portal_group *se_tpg,
-			    struct se_session *se_sess, void *p)
+int ft_sess_init(struct se_portal_group *se_tpg, struct se_session *se_sess,
+		 void *p)
 {
 	struct ft_sess *sess = p;
 	struct ft_tport *tport = sess->tport;
@@ -235,8 +235,7 @@ static struct ft_sess *ft_sess_create(struct ft_tport *tport, u32 port_id,
 	sess->se_sess = target_setup_session(se_tpg, TCM_FC_DEFAULT_TAGS,
 					     sizeof(struct ft_cmd),
 					     TARGET_PROT_NORMAL, &tpid,
-					     &initiatorname[0], sess,
-					     ft_sess_alloc_cb);
+					     &initiatorname[0], sess);
 	if (IS_ERR(sess->se_sess)) {
 		int rc = PTR_ERR(sess->se_sess);
 		kfree(sess);
diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c
index 88319b9..eab61c6 100644
--- a/drivers/usb/gadget/function/f_tcm.c
+++ b/drivers/usb/gadget/function/f_tcm.c
@@ -1551,8 +1551,8 @@ static ssize_t tcm_usbg_tpg_nexus_show(struct config_item *item, char *page)
 	return ret;
 }
 
-static int usbg_alloc_sess_cb(struct se_portal_group *se_tpg,
-			      struct se_session *se_sess, void *p)
+static int usbg_init_sess(struct se_portal_group *se_tpg,
+			  struct se_session *se_sess, void *p)
 {
 	struct usbg_tpg *tpg = container_of(se_tpg,
 				struct usbg_tpg, se_tpg);
@@ -1589,8 +1589,7 @@ static int tcm_usbg_make_nexus(struct usbg_tpg *tpg, char *name)
 						     USB_G_DEFAULT_SESSION_TAGS,
 						     sizeof(struct usbg_cmd),
 						     TARGET_PROT_NORMAL, &tpid,
-						     name, tv_nexus,
-						     usbg_alloc_sess_cb);
+						     name, tv_nexus);
 	if (IS_ERR(tv_nexus->tvn_se_sess)) {
 #define MAKE_NEXUS_MSG "core_tpg_check_initiator_node_acl() failed for %s\n"
 		pr_debug(MAKE_NEXUS_MSG, name);
@@ -1730,6 +1729,7 @@ static int usbg_check_stop_free(struct se_cmd *se_cmd)
 	.queue_tm_rsp			= usbg_queue_tm_rsp,
 	.aborted_task			= usbg_aborted_task,
 	.check_stop_free		= usbg_check_stop_free,
+	.init_session			= usbg_init_sess,
 
 	.fabric_make_wwn		= usbg_make_tport,
 	.fabric_drop_wwn		= usbg_drop_tport,
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 7ad7a92..51392ab 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -1898,8 +1898,8 @@ static ssize_t vhost_scsi_tpg_attrib_fabric_prot_type_show(
 	NULL,
 };
 
-static int vhost_scsi_nexus_cb(struct se_portal_group *se_tpg,
-			       struct se_session *se_sess, void *p)
+static int vhost_scsi_init_nexus(struct se_portal_group *se_tpg,
+				 struct se_session *se_sess, void *p)
 {
 	struct vhost_scsi_cmd *tv_cmd;
 	unsigned int i;
@@ -1983,8 +1983,7 @@ static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg, char *name)
 					VHOST_SCSI_DEFAULT_TAGS,
 					sizeof(struct vhost_scsi_cmd),
 					TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS,
-					&tpid, (unsigned char *)name, tv_nexus,
-					vhost_scsi_nexus_cb);
+					&tpid, (unsigned char *)name, tv_nexus);
 	if (IS_ERR(tv_nexus->tvn_se_sess)) {
 		mutex_unlock(&tpg->tv_tpg_mutex);
 		kfree(tv_nexus);
@@ -2317,6 +2316,7 @@ static void vhost_scsi_drop_tport(struct se_wwn *wwn)
 	.queue_status			= vhost_scsi_queue_status,
 	.queue_tm_rsp			= vhost_scsi_queue_tm_rsp,
 	.aborted_task			= vhost_scsi_aborted_task,
+	.init_session			= vhost_scsi_init_nexus,
 	/*
 	 * Setup callers for generic logic in target_core_fabric_configfs.c
 	 */
diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
index 6f9b4f7..1d8c0c2 100644
--- a/drivers/xen/xen-scsiback.c
+++ b/drivers/xen/xen-scsiback.c
@@ -1497,8 +1497,8 @@ static ssize_t scsiback_tpg_param_alias_store(struct config_item *item,
 	NULL,
 };
 
-static int scsiback_alloc_sess_cb(struct se_portal_group *se_tpg,
-				  struct se_session *se_sess, void *p)
+static int scsiback_init_sess(struct se_portal_group *se_tpg,
+			      struct se_session *se_sess, void *p)
 {
 	struct scsiback_tpg *tpg = container_of(se_tpg,
 				struct scsiback_tpg, se_tpg);
@@ -1549,8 +1549,7 @@ static int scsiback_make_nexus(struct scsiback_tpg *tpg, char *name)
 						     VSCSI_DEFAULT_SESSION_TAGS,
 						     sizeof(struct vscsibk_pend),
 						     TARGET_PROT_NORMAL, &tpid,
-						     name, tv_nexus,
-						     scsiback_alloc_sess_cb);
+						     name, tv_nexus);
 	if (IS_ERR(tv_nexus->tvn_se_sess)) {
 		kfree(tv_nexus);
 		ret = -ENOMEM;
@@ -1838,6 +1837,7 @@ static int scsiback_check_false(struct se_portal_group *se_tpg)
 	.queue_status			= scsiback_queue_status,
 	.queue_tm_rsp			= scsiback_queue_tm_rsp,
 	.aborted_task			= scsiback_aborted_task,
+	.init_session			= scsiback_init_sess,
 	/*
 	 * Setup callers for generic logic in target_core_fabric_configfs.c
 	 */
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
index be43180..509edcf 100644
--- a/include/target/target_core_fabric.h
+++ b/include/target/target_core_fabric.h
@@ -77,6 +77,9 @@ struct target_core_fabric_ops {
 
 	/* Optional session management and sysfs callouts */
 	const struct attribute_group *session_attrs;
+	int (*init_session)(struct se_portal_group *, struct se_session *,
+			    void *);
+	void (*free_session)(struct se_session *);
 
 	/*
 	 * fabric module calls for target_core_fabric_configfs.c
@@ -126,9 +129,7 @@ struct target_core_fabric_ops {
 struct t10_transport_id *target_cp_transport_id(struct t10_transport_id *);
 struct se_session *target_setup_session(struct se_portal_group *,
 		unsigned int, unsigned int, enum target_prot_op prot_op,
-		struct t10_transport_id *, const char *, void *,
-		int (*callback)(struct se_portal_group *,
-				struct se_session *, void *));
+		struct t10_transport_id *, const char *, void *);
 void target_remove_session(struct se_session *);
 
 int transport_init_session(struct se_session *se_sess);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [RFC PATCH 09/12] target: move session setup cb to fabric ops
@ 2020-04-20 19:14   ` Mike Christie
  0 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel
  Cc: Mike Christie

This moves the target_setup_session callback to the fabric ops. It also
adds a new session callback called when the session is freed. This will
be useful in the next patch for fabric mods that add session_attrs
and so we can cleanup from failures in target_setup_session.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 drivers/infiniband/ulp/srpt/ib_srpt.c    |  6 +++---
 drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c |  2 +-
 drivers/scsi/qla2xxx/tcm_qla2xxx.c       |  8 +++++---
 drivers/target/loopback/tcm_loop.c       |  8 ++++----
 drivers/target/sbp/sbp_target.c          |  2 +-
 drivers/target/target_core_transport.c   | 11 ++++++-----
 drivers/target/tcm_fc/tcm_fc.h           |  2 ++
 drivers/target/tcm_fc/tfc_conf.c         |  1 +
 drivers/target/tcm_fc/tfc_sess.c         |  7 +++----
 drivers/usb/gadget/function/f_tcm.c      |  8 ++++----
 drivers/vhost/scsi.c                     |  8 ++++----
 drivers/xen/xen-scsiback.c               |  8 ++++----
 include/target/target_core_fabric.h      |  7 ++++---
 13 files changed, 42 insertions(+), 36 deletions(-)

diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
index 4dd2a41..59a6b9b 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -2325,7 +2325,7 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev,
 			break;
 		ch->sess = target_setup_session(&stpg->tpg, tag_num,
 						tag_size, TARGET_PROT_NORMAL,
-						&tpid, ch->sess_name, ch, NULL);
+						&tpid, ch->sess_name, ch);
 	}
 	mutex_unlock(&sport->port_guid_id.mutex);
 
@@ -2335,13 +2335,13 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev,
 			break;
 		ch->sess = target_setup_session(&stpg->tpg, tag_num,
 					tag_size, TARGET_PROT_NORMAL, &tpid,
-					i_port_id, ch, NULL);
+					i_port_id, ch);
 		if (!IS_ERR_OR_NULL(ch->sess))
 			break;
 		/* Retry without leading "0x" */
 		ch->sess = target_setup_session(&stpg->tpg, tag_num,
 						tag_size, TARGET_PROT_NORMAL,
-						&tpid, i_port_id + 2, ch, NULL);
+						&tpid, i_port_id + 2, ch);
 	}
 	mutex_unlock(&sport->port_gid_id.mutex);
 
diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
index dba9ec0..23ffcd8 100644
--- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
+++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
@@ -2229,7 +2229,7 @@ static int ibmvscsis_make_nexus(struct ibmvscsis_tport *tport)
 
 	nexus->se_sess = target_setup_session(&tport->se_tpg, 0, 0,
 					      TARGET_PROT_NORMAL, &tpid, name,
-					      nexus, NULL);
+					      nexus);
 	if (IS_ERR(nexus->se_sess)) {
 		rc = PTR_ERR(nexus->se_sess);
 		goto transport_init_fail;
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index dc1bddd..d864d13 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -1389,8 +1389,8 @@ static void tcm_qla2xxx_free_session(struct fc_port *sess)
 	target_remove_session(se_sess);
 }
 
-static int tcm_qla2xxx_session_cb(struct se_portal_group *se_tpg,
-				  struct se_session *se_sess, void *p)
+static int tcm_qla2xxx_init_session(struct se_portal_group *se_tpg,
+				    struct se_session *se_sess, void *p)
 {
 	struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
 				struct tcm_qla2xxx_tpg, se_tpg);
@@ -1467,7 +1467,7 @@ static int tcm_qla2xxx_check_initiator_node_acl(
 	se_sess = target_setup_session(&tpg->se_tpg, num_tags,
 				       sizeof(struct qla_tgt_cmd),
 				       TARGET_PROT_ALL, &tpid, port_name,
-				       qlat_sess, tcm_qla2xxx_session_cb);
+				       qlat_sess);
 	if (IS_ERR(se_sess))
 		return PTR_ERR(se_sess);
 
@@ -1832,6 +1832,7 @@ static ssize_t tcm_qla2xxx_wwn_version_show(struct config_item *item,
 	.check_stop_free		= tcm_qla2xxx_check_stop_free,
 	.release_cmd			= tcm_qla2xxx_release_cmd,
 	.close_session			= tcm_qla2xxx_close_session,
+	.init_session			= tcm_qla2xxx_init_session,
 	.sess_get_index			= tcm_qla2xxx_sess_get_index,
 	.write_pending			= tcm_qla2xxx_write_pending,
 	.set_default_node_attributes	= tcm_qla2xxx_set_default_node_attrs,
@@ -1871,6 +1872,7 @@ static ssize_t tcm_qla2xxx_wwn_version_show(struct config_item *item,
 	.check_stop_free                = tcm_qla2xxx_check_stop_free,
 	.release_cmd			= tcm_qla2xxx_release_cmd,
 	.close_session			= tcm_qla2xxx_close_session,
+	.init_session			= tcm_qla2xxx_init_session,
 	.sess_get_index			= tcm_qla2xxx_sess_get_index,
 	.write_pending			= tcm_qla2xxx_write_pending,
 	.set_default_node_attributes	= tcm_qla2xxx_set_default_node_attrs,
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index 7593a53..7025b7e 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -713,8 +713,8 @@ static ssize_t tcm_loop_tpg_attrib_fabric_prot_type_store(
 
 /* Start items for tcm_loop_nexus_cit */
 
-static int tcm_loop_alloc_sess_cb(struct se_portal_group *se_tpg,
-				  struct se_session *se_sess, void *p)
+static int tcm_loop_init_sess(struct se_portal_group *se_tpg,
+			      struct se_session *se_sess, void *p)
 {
 	struct tcm_loop_tpg *tl_tpg = container_of(se_tpg,
 					struct tcm_loop_tpg, tl_se_tpg);
@@ -761,8 +761,7 @@ static int tcm_loop_make_nexus(
 
 	tl_nexus->se_sess = target_setup_session(&tl_tpg->tl_se_tpg, 0, 0,
 					TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS,
-					&tpid, name, tl_nexus,
-					tcm_loop_alloc_sess_cb);
+					&tpid, name, tl_nexus);
 	if (IS_ERR(tl_nexus->se_sess)) {
 		ret = PTR_ERR(tl_nexus->se_sess);
 		kfree(tl_nexus);
@@ -1165,6 +1164,7 @@ static ssize_t tcm_loop_wwn_version_show(struct config_item *item, char *page)
 	.queue_status			= tcm_loop_queue_status,
 	.queue_tm_rsp			= tcm_loop_queue_tm_rsp,
 	.aborted_task			= tcm_loop_aborted_task,
+	.init_session			= tcm_loop_init_sess,
 	.fabric_make_wwn		= tcm_loop_make_scsi_hba,
 	.fabric_drop_wwn		= tcm_loop_drop_scsi_hba,
 	.fabric_make_tpg		= tcm_loop_make_naa_tpg,
diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c
index 9a3121d..20f8b3b 100644
--- a/drivers/target/sbp/sbp_target.c
+++ b/drivers/target/sbp/sbp_target.c
@@ -204,7 +204,7 @@ static struct sbp_session *sbp_session_create(
 	sess->se_sess = target_setup_session(&tpg->se_tpg, 128,
 					     sizeof(struct sbp_target_request),
 					     TARGET_PROT_NORMAL, &tpid,
-					     guid_str, sess, NULL);
+					     guid_str, sess);
 	if (IS_ERR(sess->se_sess)) {
 		pr_err("failed to init se_session\n");
 		ret = PTR_ERR(sess->se_sess);
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index d3248d4..7aa830e 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -434,9 +434,7 @@ struct se_session *
 target_setup_session(struct se_portal_group *tpg,
 		     unsigned int tag_num, unsigned int tag_size,
 		     enum target_prot_op prot_op, struct t10_transport_id *tpid,
-		     const char *initiatorname, void *private,
-		     int (*callback)(struct se_portal_group *,
-				     struct se_session *, void *))
+		     const char *initiatorname, void *private)
 {
 	struct se_session *sess;
 	int rc;
@@ -469,8 +467,8 @@ struct se_session *
 	 * Go ahead and perform any remaining fabric setup that is
 	 * required before transport_register_session().
 	 */
-	if (callback != NULL) {
-		rc = callback(tpg, sess, private);
+	if (tpg->se_tpg_tfo->init_session) {
+		rc = tpg->se_tpg_tfo->init_session(tpg, sess, private);
 		if (rc)
 			goto free_sess;
 	}
@@ -612,6 +610,9 @@ void transport_free_session(struct se_session *se_sess)
 
 void __target_free_session(struct se_session *se_sess)
 {
+	if (se_sess->tfo && se_sess->tfo->free_session)
+		se_sess->tfo->free_session(se_sess);
+
 	kfree(se_sess->acl_name);
 	target_free_transport_id(se_sess->tpid);
 
diff --git a/drivers/target/tcm_fc/tcm_fc.h b/drivers/target/tcm_fc/tcm_fc.h
index 2ff716d..ce07b3e 100644
--- a/drivers/target/tcm_fc/tcm_fc.h
+++ b/drivers/target/tcm_fc/tcm_fc.h
@@ -129,6 +129,8 @@ struct ft_cmd {
 /*
  * Session ops.
  */
+
+int ft_sess_init(struct se_portal_group *, struct se_session *, void *);
 void ft_sess_put(struct ft_sess *);
 void ft_sess_close(struct se_session *);
 u32 ft_sess_get_index(struct se_session *);
diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c
index 870b7bb..7983554 100644
--- a/drivers/target/tcm_fc/tfc_conf.c
+++ b/drivers/target/tcm_fc/tfc_conf.c
@@ -426,6 +426,7 @@ static u32 ft_tpg_get_inst_index(struct se_portal_group *se_tpg)
 	.check_stop_free =		ft_check_stop_free,
 	.release_cmd =			ft_release_cmd,
 	.close_session =		ft_sess_close,
+	.init_session =			ft_sess_init,
 	.sess_get_index =		ft_sess_get_index,
 	.write_pending =		ft_write_pending,
 	.set_default_node_attributes =	ft_set_default_node_attr,
diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c
index f261756..7357c38 100644
--- a/drivers/target/tcm_fc/tfc_sess.c
+++ b/drivers/target/tcm_fc/tfc_sess.c
@@ -186,8 +186,8 @@ static struct ft_sess *ft_sess_get(struct fc_lport *lport, u32 port_id)
 	return NULL;
 }
 
-static int ft_sess_alloc_cb(struct se_portal_group *se_tpg,
-			    struct se_session *se_sess, void *p)
+int ft_sess_init(struct se_portal_group *se_tpg, struct se_session *se_sess,
+		 void *p)
 {
 	struct ft_sess *sess = p;
 	struct ft_tport *tport = sess->tport;
@@ -235,8 +235,7 @@ static struct ft_sess *ft_sess_create(struct ft_tport *tport, u32 port_id,
 	sess->se_sess = target_setup_session(se_tpg, TCM_FC_DEFAULT_TAGS,
 					     sizeof(struct ft_cmd),
 					     TARGET_PROT_NORMAL, &tpid,
-					     &initiatorname[0], sess,
-					     ft_sess_alloc_cb);
+					     &initiatorname[0], sess);
 	if (IS_ERR(sess->se_sess)) {
 		int rc = PTR_ERR(sess->se_sess);
 		kfree(sess);
diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c
index 88319b9..eab61c6 100644
--- a/drivers/usb/gadget/function/f_tcm.c
+++ b/drivers/usb/gadget/function/f_tcm.c
@@ -1551,8 +1551,8 @@ static ssize_t tcm_usbg_tpg_nexus_show(struct config_item *item, char *page)
 	return ret;
 }
 
-static int usbg_alloc_sess_cb(struct se_portal_group *se_tpg,
-			      struct se_session *se_sess, void *p)
+static int usbg_init_sess(struct se_portal_group *se_tpg,
+			  struct se_session *se_sess, void *p)
 {
 	struct usbg_tpg *tpg = container_of(se_tpg,
 				struct usbg_tpg, se_tpg);
@@ -1589,8 +1589,7 @@ static int tcm_usbg_make_nexus(struct usbg_tpg *tpg, char *name)
 						     USB_G_DEFAULT_SESSION_TAGS,
 						     sizeof(struct usbg_cmd),
 						     TARGET_PROT_NORMAL, &tpid,
-						     name, tv_nexus,
-						     usbg_alloc_sess_cb);
+						     name, tv_nexus);
 	if (IS_ERR(tv_nexus->tvn_se_sess)) {
 #define MAKE_NEXUS_MSG "core_tpg_check_initiator_node_acl() failed for %s\n"
 		pr_debug(MAKE_NEXUS_MSG, name);
@@ -1730,6 +1729,7 @@ static int usbg_check_stop_free(struct se_cmd *se_cmd)
 	.queue_tm_rsp			= usbg_queue_tm_rsp,
 	.aborted_task			= usbg_aborted_task,
 	.check_stop_free		= usbg_check_stop_free,
+	.init_session			= usbg_init_sess,
 
 	.fabric_make_wwn		= usbg_make_tport,
 	.fabric_drop_wwn		= usbg_drop_tport,
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 7ad7a92..51392ab 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -1898,8 +1898,8 @@ static ssize_t vhost_scsi_tpg_attrib_fabric_prot_type_show(
 	NULL,
 };
 
-static int vhost_scsi_nexus_cb(struct se_portal_group *se_tpg,
-			       struct se_session *se_sess, void *p)
+static int vhost_scsi_init_nexus(struct se_portal_group *se_tpg,
+				 struct se_session *se_sess, void *p)
 {
 	struct vhost_scsi_cmd *tv_cmd;
 	unsigned int i;
@@ -1983,8 +1983,7 @@ static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg, char *name)
 					VHOST_SCSI_DEFAULT_TAGS,
 					sizeof(struct vhost_scsi_cmd),
 					TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS,
-					&tpid, (unsigned char *)name, tv_nexus,
-					vhost_scsi_nexus_cb);
+					&tpid, (unsigned char *)name, tv_nexus);
 	if (IS_ERR(tv_nexus->tvn_se_sess)) {
 		mutex_unlock(&tpg->tv_tpg_mutex);
 		kfree(tv_nexus);
@@ -2317,6 +2316,7 @@ static void vhost_scsi_drop_tport(struct se_wwn *wwn)
 	.queue_status			= vhost_scsi_queue_status,
 	.queue_tm_rsp			= vhost_scsi_queue_tm_rsp,
 	.aborted_task			= vhost_scsi_aborted_task,
+	.init_session			= vhost_scsi_init_nexus,
 	/*
 	 * Setup callers for generic logic in target_core_fabric_configfs.c
 	 */
diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
index 6f9b4f7..1d8c0c2 100644
--- a/drivers/xen/xen-scsiback.c
+++ b/drivers/xen/xen-scsiback.c
@@ -1497,8 +1497,8 @@ static ssize_t scsiback_tpg_param_alias_store(struct config_item *item,
 	NULL,
 };
 
-static int scsiback_alloc_sess_cb(struct se_portal_group *se_tpg,
-				  struct se_session *se_sess, void *p)
+static int scsiback_init_sess(struct se_portal_group *se_tpg,
+			      struct se_session *se_sess, void *p)
 {
 	struct scsiback_tpg *tpg = container_of(se_tpg,
 				struct scsiback_tpg, se_tpg);
@@ -1549,8 +1549,7 @@ static int scsiback_make_nexus(struct scsiback_tpg *tpg, char *name)
 						     VSCSI_DEFAULT_SESSION_TAGS,
 						     sizeof(struct vscsibk_pend),
 						     TARGET_PROT_NORMAL, &tpid,
-						     name, tv_nexus,
-						     scsiback_alloc_sess_cb);
+						     name, tv_nexus);
 	if (IS_ERR(tv_nexus->tvn_se_sess)) {
 		kfree(tv_nexus);
 		ret = -ENOMEM;
@@ -1838,6 +1837,7 @@ static int scsiback_check_false(struct se_portal_group *se_tpg)
 	.queue_status			= scsiback_queue_status,
 	.queue_tm_rsp			= scsiback_queue_tm_rsp,
 	.aborted_task			= scsiback_aborted_task,
+	.init_session			= scsiback_init_sess,
 	/*
 	 * Setup callers for generic logic in target_core_fabric_configfs.c
 	 */
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
index be43180..509edcf 100644
--- a/include/target/target_core_fabric.h
+++ b/include/target/target_core_fabric.h
@@ -77,6 +77,9 @@ struct target_core_fabric_ops {
 
 	/* Optional session management and sysfs callouts */
 	const struct attribute_group *session_attrs;
+	int (*init_session)(struct se_portal_group *, struct se_session *,
+			    void *);
+	void (*free_session)(struct se_session *);
 
 	/*
 	 * fabric module calls for target_core_fabric_configfs.c
@@ -126,9 +129,7 @@ struct target_core_fabric_ops {
 struct t10_transport_id *target_cp_transport_id(struct t10_transport_id *);
 struct se_session *target_setup_session(struct se_portal_group *,
 		unsigned int, unsigned int, enum target_prot_op prot_op,
-		struct t10_transport_id *, const char *, void *,
-		int (*callback)(struct se_portal_group *,
-				struct se_session *, void *));
+		struct t10_transport_id *, const char *, void *);
 void target_remove_session(struct se_session *);
 
 int transport_init_session(struct se_session *se_sess);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [RFC PATCH 10/12] target: add target_setup_session sysfs support
  2020-04-20 19:14 ` Mike Christie
@ 2020-04-20 19:14   ` Mike Christie
  -1 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel
  Cc: Mike Christie

This adds a session dir per session for users of target_setup_session.

TODO:
1. drivers like tcm_qla2xxx allocate resources in the fabric ops
init_session callback, but I have not implemented free_session
callbacks for them yet.

2. Drivers that delete their tpg before the sessions need to
be updated.

Signed-off-by: Mike Christie <mchristi@redhat.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 7aa830e..fd41f35 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -472,10 +472,24 @@ struct se_session *
 		if (rc)
 			goto free_sess;
 	}
+	/*
+	 * init_session was successful so set the tfo now, because if there
+	 * is a failure going forward we will want to call the free_session
+	 * callback.
+	 */
+	sess->tfo = tpg->se_tpg_tfo;
 
 	transport_register_session(tpg, sess->se_node_acl, sess, private);
+
+	rc = target_sysfs_add_session(tpg, sess);
+	if (rc)
+		goto dereg_sess;
+
 	return sess;
 
+dereg_sess:
+	transport_deregister_session_configfs(sess);
+	transport_deregister_session(sess);
 free_sess:
 	transport_free_session(sess);
 	return ERR_PTR(rc);
@@ -671,6 +685,7 @@ void transport_deregister_session(struct se_session *se_sess)
 
 void target_remove_session(struct se_session *se_sess)
 {
+	target_sysfs_remove_session(se_sess);
 	transport_deregister_session_configfs(se_sess);
 	transport_deregister_session(se_sess);
 }
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [RFC PATCH 10/12] target: add target_setup_session sysfs support
@ 2020-04-20 19:14   ` Mike Christie
  0 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel
  Cc: Mike Christie

This adds a session dir per session for users of target_setup_session.

TODO:
1. drivers like tcm_qla2xxx allocate resources in the fabric ops
init_session callback, but I have not implemented free_session
callbacks for them yet.

2. Drivers that delete their tpg before the sessions need to
be updated.

Signed-off-by: Mike Christie <mchristi@redhat.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 7aa830e..fd41f35 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -472,10 +472,24 @@ struct se_session *
 		if (rc)
 			goto free_sess;
 	}
+	/*
+	 * init_session was successful so set the tfo now, because if there
+	 * is a failure going forward we will want to call the free_session
+	 * callback.
+	 */
+	sess->tfo = tpg->se_tpg_tfo;
 
 	transport_register_session(tpg, sess->se_node_acl, sess, private);
+
+	rc = target_sysfs_add_session(tpg, sess);
+	if (rc)
+		goto dereg_sess;
+
 	return sess;
 
+dereg_sess:
+	transport_deregister_session_configfs(sess);
+	transport_deregister_session(sess);
 free_sess:
 	transport_free_session(sess);
 	return ERR_PTR(rc);
@@ -671,6 +685,7 @@ void transport_deregister_session(struct se_session *se_sess)
 
 void target_remove_session(struct se_session *se_sess)
 {
+	target_sysfs_remove_session(se_sess);
 	transport_deregister_session_configfs(se_sess);
 	transport_deregister_session(se_sess);
 }
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [RFC PATCH 11/12] iscsi target: use session sysfs helpers
  2020-04-20 19:14 ` Mike Christie
@ 2020-04-20 19:14   ` Mike Christie
  -1 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel
  Cc: Mike Christie

The iscsi target login process breaks up session allocation and
registration, so it does not use target_setup_session like every one
else. This converts iscsi to use the session sysfs helpers and drops its
session id to use the common one.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 drivers/target/iscsi/iscsi_target.c          |  4 ++--
 drivers/target/iscsi/iscsi_target_configfs.c |  4 +---
 drivers/target/iscsi/iscsi_target_login.c    | 16 ++--------------
 drivers/target/iscsi/iscsi_target_nego.c     |  6 ++++++
 drivers/target/iscsi/iscsi_target_stat.c     |  3 +--
 include/target/iscsi/iscsi_target_core.h     |  2 --
 6 files changed, 12 insertions(+), 23 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 09e55ea..29163ae 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -49,7 +49,6 @@
 static DEFINE_MUTEX(np_lock);
 
 static struct idr tiqn_idr;
-DEFINE_IDA(sess_ida);
 struct mutex auth_id_lock;
 
 struct iscsit_global *iscsit_global;
@@ -4352,6 +4351,8 @@ int iscsit_close_session(struct iscsi_session *sess)
 	iscsit_stop_time2retain_timer(sess);
 	spin_unlock_bh(&se_tpg->session_lock);
 
+	target_sysfs_remove_session(sess->se_sess);
+
 	/*
 	 * transport_deregister_session_configfs() will clear the
 	 * struct se_node_acl->nacl_sess pointer now as a iscsi_np process context
@@ -4397,7 +4398,6 @@ int iscsit_close_session(struct iscsi_session *sess)
 	pr_debug("Decremented number of active iSCSI Sessions on"
 		" iSCSI TPG: %hu to %u\n", tpg->tpgt, tpg->nsessions);
 
-	ida_free(&sess_ida, sess->session_index);
 	kfree(sess->sess_ops);
 	sess->sess_ops = NULL;
 	spin_unlock_bh(&se_tpg->session_lock);
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c
index f640e7a..c40cff1 100644
--- a/drivers/target/iscsi/iscsi_target_configfs.c
+++ b/drivers/target/iscsi/iscsi_target_configfs.c
@@ -1344,9 +1344,7 @@ static int iscsi_get_cmd_state(struct se_cmd *se_cmd)
 
 static u32 lio_sess_get_index(struct se_session *se_sess)
 {
-	struct iscsi_session *sess = se_sess->fabric_sess_ptr;
-
-	return sess->session_index;
+	return se_sess->sid;
 }
 
 static int lio_queue_data_in(struct se_cmd *se_cmd)
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
index f533308..a0ea60f 100644
--- a/drivers/target/iscsi/iscsi_target_login.c
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -257,7 +257,6 @@ static int iscsi_login_zero_tsih_s1(
 {
 	struct iscsi_session *sess = NULL;
 	struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf;
-	int ret;
 
 	sess = kzalloc(sizeof(struct iscsi_session), GFP_KERNEL);
 	if (!sess) {
@@ -291,15 +290,6 @@ static int iscsi_login_zero_tsih_s1(
 	timer_setup(&sess->time2retain_timer,
 		    iscsit_handle_time2retain_timeout, 0);
 
-	ret = ida_alloc(&sess_ida, GFP_KERNEL);
-	if (ret < 0) {
-		pr_err("Session ID allocation failed %d\n", ret);
-		iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
-				ISCSI_LOGIN_STATUS_NO_RESOURCES);
-		goto free_sess;
-	}
-
-	sess->session_index = ret;
 	sess->creation_time = get_jiffies_64();
 	/*
 	 * The FFP CmdSN window values will be allocated from the TPG's
@@ -313,7 +303,7 @@ static int iscsi_login_zero_tsih_s1(
 				ISCSI_LOGIN_STATUS_NO_RESOURCES);
 		pr_err("Unable to allocate memory for"
 				" struct iscsi_sess_ops.\n");
-		goto free_id;
+		goto free_ops;
 	}
 
 	sess->se_sess = transport_alloc_session(TARGET_PROT_NORMAL);
@@ -327,8 +317,6 @@ static int iscsi_login_zero_tsih_s1(
 
 free_ops:
 	kfree(sess->sess_ops);
-free_id:
-	ida_free(&sess_ida, sess->session_index);
 free_sess:
 	kfree(sess);
 	conn->sess = NULL;
@@ -1182,8 +1170,8 @@ void iscsi_target_login_sess_out(struct iscsi_conn *conn,
 	if (!zero_tsih || !conn->sess)
 		goto old_sess_out;
 
+	target_sysfs_remove_session(conn->sess->se_sess);
 	transport_free_session(conn->sess->se_sess);
-	ida_free(&sess_ida, conn->sess->session_index);
 	kfree(conn->sess->sess_ops);
 	kfree(conn->sess);
 	conn->sess = NULL;
diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c
index dd9bfa7..89d54b6 100644
--- a/drivers/target/iscsi/iscsi_target_nego.c
+++ b/drivers/target/iscsi/iscsi_target_nego.c
@@ -1282,11 +1282,17 @@ int iscsi_target_locate_portal(
 	ret = transport_alloc_session_tags(sess->se_sess, tag_num, tag_size);
 	if (ret < 0)
 		goto return_oom;
+	sess->se_sess->tfo = &iscsi_ops;
 
 	if (conn->tpg != iscsit_global->discovery_tpg) {
 		if (iscsi_setup_i_tpid(sess, i_buf))
 			/* tags and nacl released when session is freed */
 			goto return_oom;
+
+		if (target_sysfs_add_session(&conn->tpg->tpg_se_tpg,
+					     sess->se_sess))
+			/* tpid is freed when session is freed */
+			goto return_oom;
 	}
 
 	goto out;
diff --git a/drivers/target/iscsi/iscsi_target_stat.c b/drivers/target/iscsi/iscsi_target_stat.c
index 35e75a3..8167fdc 100644
--- a/drivers/target/iscsi/iscsi_target_stat.c
+++ b/drivers/target/iscsi/iscsi_target_stat.c
@@ -630,8 +630,7 @@ static ssize_t iscsi_stat_sess_indx_show(struct config_item *item, char *page)
 	if (se_sess) {
 		sess = se_sess->fabric_sess_ptr;
 		if (sess)
-			ret = snprintf(page, PAGE_SIZE, "%u\n",
-					sess->session_index);
+			ret = snprintf(page, PAGE_SIZE, "%u\n", se_sess->sid);
 	}
 	spin_unlock_bh(&se_nacl->nacl_sess_lock);
 
diff --git a/include/target/iscsi/iscsi_target_core.h b/include/target/iscsi/iscsi_target_core.h
index a49d371..aeabb83 100644
--- a/include/target/iscsi/iscsi_target_core.h
+++ b/include/target/iscsi/iscsi_target_core.h
@@ -657,8 +657,6 @@ struct iscsi_session {
 	/* LIO specific session ID */
 	u32			sid;
 	char			auth_type[8];
-	/* unique within the target */
-	int			session_index;
 	/* Used for session reference counting */
 	int			session_usage_count;
 	int			session_waiting_on_uc;
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [RFC PATCH 11/12] iscsi target: use session sysfs helpers
@ 2020-04-20 19:14   ` Mike Christie
  0 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel
  Cc: Mike Christie

The iscsi target login process breaks up session allocation and
registration, so it does not use target_setup_session like every one
else. This converts iscsi to use the session sysfs helpers and drops its
session id to use the common one.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 drivers/target/iscsi/iscsi_target.c          |  4 ++--
 drivers/target/iscsi/iscsi_target_configfs.c |  4 +---
 drivers/target/iscsi/iscsi_target_login.c    | 16 ++--------------
 drivers/target/iscsi/iscsi_target_nego.c     |  6 ++++++
 drivers/target/iscsi/iscsi_target_stat.c     |  3 +--
 include/target/iscsi/iscsi_target_core.h     |  2 --
 6 files changed, 12 insertions(+), 23 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 09e55ea..29163ae 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -49,7 +49,6 @@
 static DEFINE_MUTEX(np_lock);
 
 static struct idr tiqn_idr;
-DEFINE_IDA(sess_ida);
 struct mutex auth_id_lock;
 
 struct iscsit_global *iscsit_global;
@@ -4352,6 +4351,8 @@ int iscsit_close_session(struct iscsi_session *sess)
 	iscsit_stop_time2retain_timer(sess);
 	spin_unlock_bh(&se_tpg->session_lock);
 
+	target_sysfs_remove_session(sess->se_sess);
+
 	/*
 	 * transport_deregister_session_configfs() will clear the
 	 * struct se_node_acl->nacl_sess pointer now as a iscsi_np process context
@@ -4397,7 +4398,6 @@ int iscsit_close_session(struct iscsi_session *sess)
 	pr_debug("Decremented number of active iSCSI Sessions on"
 		" iSCSI TPG: %hu to %u\n", tpg->tpgt, tpg->nsessions);
 
-	ida_free(&sess_ida, sess->session_index);
 	kfree(sess->sess_ops);
 	sess->sess_ops = NULL;
 	spin_unlock_bh(&se_tpg->session_lock);
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c
index f640e7a..c40cff1 100644
--- a/drivers/target/iscsi/iscsi_target_configfs.c
+++ b/drivers/target/iscsi/iscsi_target_configfs.c
@@ -1344,9 +1344,7 @@ static int iscsi_get_cmd_state(struct se_cmd *se_cmd)
 
 static u32 lio_sess_get_index(struct se_session *se_sess)
 {
-	struct iscsi_session *sess = se_sess->fabric_sess_ptr;
-
-	return sess->session_index;
+	return se_sess->sid;
 }
 
 static int lio_queue_data_in(struct se_cmd *se_cmd)
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
index f533308..a0ea60f 100644
--- a/drivers/target/iscsi/iscsi_target_login.c
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -257,7 +257,6 @@ static int iscsi_login_zero_tsih_s1(
 {
 	struct iscsi_session *sess = NULL;
 	struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf;
-	int ret;
 
 	sess = kzalloc(sizeof(struct iscsi_session), GFP_KERNEL);
 	if (!sess) {
@@ -291,15 +290,6 @@ static int iscsi_login_zero_tsih_s1(
 	timer_setup(&sess->time2retain_timer,
 		    iscsit_handle_time2retain_timeout, 0);
 
-	ret = ida_alloc(&sess_ida, GFP_KERNEL);
-	if (ret < 0) {
-		pr_err("Session ID allocation failed %d\n", ret);
-		iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
-				ISCSI_LOGIN_STATUS_NO_RESOURCES);
-		goto free_sess;
-	}
-
-	sess->session_index = ret;
 	sess->creation_time = get_jiffies_64();
 	/*
 	 * The FFP CmdSN window values will be allocated from the TPG's
@@ -313,7 +303,7 @@ static int iscsi_login_zero_tsih_s1(
 				ISCSI_LOGIN_STATUS_NO_RESOURCES);
 		pr_err("Unable to allocate memory for"
 				" struct iscsi_sess_ops.\n");
-		goto free_id;
+		goto free_ops;
 	}
 
 	sess->se_sess = transport_alloc_session(TARGET_PROT_NORMAL);
@@ -327,8 +317,6 @@ static int iscsi_login_zero_tsih_s1(
 
 free_ops:
 	kfree(sess->sess_ops);
-free_id:
-	ida_free(&sess_ida, sess->session_index);
 free_sess:
 	kfree(sess);
 	conn->sess = NULL;
@@ -1182,8 +1170,8 @@ void iscsi_target_login_sess_out(struct iscsi_conn *conn,
 	if (!zero_tsih || !conn->sess)
 		goto old_sess_out;
 
+	target_sysfs_remove_session(conn->sess->se_sess);
 	transport_free_session(conn->sess->se_sess);
-	ida_free(&sess_ida, conn->sess->session_index);
 	kfree(conn->sess->sess_ops);
 	kfree(conn->sess);
 	conn->sess = NULL;
diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c
index dd9bfa7..89d54b6 100644
--- a/drivers/target/iscsi/iscsi_target_nego.c
+++ b/drivers/target/iscsi/iscsi_target_nego.c
@@ -1282,11 +1282,17 @@ int iscsi_target_locate_portal(
 	ret = transport_alloc_session_tags(sess->se_sess, tag_num, tag_size);
 	if (ret < 0)
 		goto return_oom;
+	sess->se_sess->tfo = &iscsi_ops;
 
 	if (conn->tpg != iscsit_global->discovery_tpg) {
 		if (iscsi_setup_i_tpid(sess, i_buf))
 			/* tags and nacl released when session is freed */
 			goto return_oom;
+
+		if (target_sysfs_add_session(&conn->tpg->tpg_se_tpg,
+					     sess->se_sess))
+			/* tpid is freed when session is freed */
+			goto return_oom;
 	}
 
 	goto out;
diff --git a/drivers/target/iscsi/iscsi_target_stat.c b/drivers/target/iscsi/iscsi_target_stat.c
index 35e75a3..8167fdc 100644
--- a/drivers/target/iscsi/iscsi_target_stat.c
+++ b/drivers/target/iscsi/iscsi_target_stat.c
@@ -630,8 +630,7 @@ static ssize_t iscsi_stat_sess_indx_show(struct config_item *item, char *page)
 	if (se_sess) {
 		sess = se_sess->fabric_sess_ptr;
 		if (sess)
-			ret = snprintf(page, PAGE_SIZE, "%u\n",
-					sess->session_index);
+			ret = snprintf(page, PAGE_SIZE, "%u\n", se_sess->sid);
 	}
 	spin_unlock_bh(&se_nacl->nacl_sess_lock);
 
diff --git a/include/target/iscsi/iscsi_target_core.h b/include/target/iscsi/iscsi_target_core.h
index a49d371..aeabb83 100644
--- a/include/target/iscsi/iscsi_target_core.h
+++ b/include/target/iscsi/iscsi_target_core.h
@@ -657,8 +657,6 @@ struct iscsi_session {
 	/* LIO specific session ID */
 	u32			sid;
 	char			auth_type[8];
-	/* unique within the target */
-	int			session_index;
 	/* Used for session reference counting */
 	int			session_usage_count;
 	int			session_waiting_on_uc;
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [RFC PATCH 12/12] target: drop sess_get_index
  2020-04-20 19:14 ` Mike Christie
@ 2020-04-20 19:14   ` Mike Christie
  -1 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel
  Cc: Mike Christie

LIO now handles session id allocation so drop the callout.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 drivers/infiniband/ulp/srpt/ib_srpt.c        | 15 ---------------
 drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c     |  6 ------
 drivers/scsi/qla2xxx/tcm_qla2xxx.c           |  7 -------
 drivers/target/iscsi/iscsi_target_configfs.c |  6 ------
 drivers/target/loopback/tcm_loop.c           |  6 ------
 drivers/target/sbp/sbp_target.c              |  6 ------
 drivers/target/target_core_configfs.c        |  4 ----
 drivers/target/target_core_stat.c            |  5 +----
 drivers/target/tcm_fc/tfc_conf.c             |  1 -
 drivers/target/tcm_fc/tfc_sess.c             |  7 -------
 drivers/usb/gadget/function/f_tcm.c          |  6 ------
 drivers/vhost/scsi.c                         |  6 ------
 drivers/xen/xen-scsiback.c                   |  6 ------
 include/target/target_core_fabric.h          |  1 -
 14 files changed, 1 insertion(+), 81 deletions(-)

diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
index 59a6b9b..87330bb 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -3356,20 +3356,6 @@ static void srpt_close_session(struct se_session *se_sess)
 	srpt_disconnect_ch_sync(ch);
 }
 
-/**
- * srpt_sess_get_index - return the value of scsiAttIntrPortIndex (SCSI-MIB)
- * @se_sess: SCSI target session.
- *
- * A quote from RFC 4455 (SCSI-MIB) about this MIB object:
- * This object represents an arbitrary integer used to uniquely identify a
- * particular attached remote initiator port to a particular SCSI target port
- * within a particular SCSI target device within a particular SCSI instance.
- */
-static u32 srpt_sess_get_index(struct se_session *se_sess)
-{
-	return 0;
-}
-
 static void srpt_set_default_node_attrs(struct se_node_acl *nacl)
 {
 }
@@ -3846,7 +3832,6 @@ static ssize_t srpt_wwn_version_show(struct config_item *item, char *buf)
 	.release_cmd			= srpt_release_cmd,
 	.check_stop_free		= srpt_check_stop_free,
 	.close_session			= srpt_close_session,
-	.sess_get_index			= srpt_sess_get_index,
 	.write_pending			= srpt_write_pending,
 	.set_default_node_attributes	= srpt_set_default_node_attrs,
 	.get_cmd_state			= srpt_get_tcm_cmd_state,
diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
index 23ffcd8..42b3c83 100644
--- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
+++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
@@ -3744,11 +3744,6 @@ static void ibmvscsis_release_cmd(struct se_cmd *se_cmd)
 	spin_unlock_bh(&vscsi->intr_lock);
 }
 
-static u32 ibmvscsis_sess_get_index(struct se_session *se_sess)
-{
-	return 0;
-}
-
 static int ibmvscsis_write_pending(struct se_cmd *se_cmd)
 {
 	struct ibmvscsis_cmd *cmd = container_of(se_cmd, struct ibmvscsis_cmd,
@@ -4039,7 +4034,6 @@ static ssize_t ibmvscsis_tpg_enable_store(struct config_item *item,
 	.tpg_get_inst_index		= ibmvscsis_tpg_get_inst_index,
 	.check_stop_free		= ibmvscsis_check_stop_free,
 	.release_cmd			= ibmvscsis_release_cmd,
-	.sess_get_index			= ibmvscsis_sess_get_index,
 	.write_pending			= ibmvscsis_write_pending,
 	.set_default_node_attributes	= ibmvscsis_set_default_node_attrs,
 	.get_cmd_state			= ibmvscsis_get_cmd_state,
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index d864d13..a60dc89 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -354,11 +354,6 @@ static void tcm_qla2xxx_close_session(struct se_session *se_sess)
 	tcm_qla2xxx_put_sess(sess);
 }
 
-static u32 tcm_qla2xxx_sess_get_index(struct se_session *se_sess)
-{
-	return 0;
-}
-
 static int tcm_qla2xxx_write_pending(struct se_cmd *se_cmd)
 {
 	struct qla_tgt_cmd *cmd = container_of(se_cmd,
@@ -1833,7 +1828,6 @@ static ssize_t tcm_qla2xxx_wwn_version_show(struct config_item *item,
 	.release_cmd			= tcm_qla2xxx_release_cmd,
 	.close_session			= tcm_qla2xxx_close_session,
 	.init_session			= tcm_qla2xxx_init_session,
-	.sess_get_index			= tcm_qla2xxx_sess_get_index,
 	.write_pending			= tcm_qla2xxx_write_pending,
 	.set_default_node_attributes	= tcm_qla2xxx_set_default_node_attrs,
 	.get_cmd_state			= tcm_qla2xxx_get_cmd_state,
@@ -1873,7 +1867,6 @@ static ssize_t tcm_qla2xxx_wwn_version_show(struct config_item *item,
 	.release_cmd			= tcm_qla2xxx_release_cmd,
 	.close_session			= tcm_qla2xxx_close_session,
 	.init_session			= tcm_qla2xxx_init_session,
-	.sess_get_index			= tcm_qla2xxx_sess_get_index,
 	.write_pending			= tcm_qla2xxx_write_pending,
 	.set_default_node_attributes	= tcm_qla2xxx_set_default_node_attrs,
 	.get_cmd_state			= tcm_qla2xxx_get_cmd_state,
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c
index c40cff1..0b98245 100644
--- a/drivers/target/iscsi/iscsi_target_configfs.c
+++ b/drivers/target/iscsi/iscsi_target_configfs.c
@@ -1342,11 +1342,6 @@ static int iscsi_get_cmd_state(struct se_cmd *se_cmd)
 	return cmd->i_state;
 }
 
-static u32 lio_sess_get_index(struct se_session *se_sess)
-{
-	return se_sess->sid;
-}
-
 static int lio_queue_data_in(struct se_cmd *se_cmd)
 {
 	struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
@@ -1527,7 +1522,6 @@ static void lio_release_cmd(struct se_cmd *se_cmd)
 	.check_stop_free		= lio_check_stop_free,
 	.release_cmd			= lio_release_cmd,
 	.close_session			= lio_tpg_close_session,
-	.sess_get_index			= lio_sess_get_index,
 	.write_pending			= lio_write_pending,
 	.set_default_node_attributes	= lio_set_default_node_attributes,
 	.get_cmd_state			= iscsi_get_cmd_state,
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index 7025b7e..1d92c36 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -512,11 +512,6 @@ static u32 tcm_loop_get_inst_index(struct se_portal_group *se_tpg)
 	return 1;
 }
 
-static u32 tcm_loop_sess_get_index(struct se_session *se_sess)
-{
-	return 1;
-}
-
 static void tcm_loop_set_default_node_attributes(struct se_node_acl *se_acl)
 {
 	return;
@@ -1156,7 +1151,6 @@ static ssize_t tcm_loop_wwn_version_show(struct config_item *item, char *page)
 	.tpg_get_inst_index		= tcm_loop_get_inst_index,
 	.check_stop_free		= tcm_loop_check_stop_free,
 	.release_cmd			= tcm_loop_release_cmd,
-	.sess_get_index			= tcm_loop_sess_get_index,
 	.write_pending			= tcm_loop_write_pending,
 	.set_default_node_attributes	= tcm_loop_set_default_node_attributes,
 	.get_cmd_state			= tcm_loop_get_cmd_state,
diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c
index 20f8b3b..a3d868b 100644
--- a/drivers/target/sbp/sbp_target.c
+++ b/drivers/target/sbp/sbp_target.c
@@ -1713,11 +1713,6 @@ static void sbp_release_cmd(struct se_cmd *se_cmd)
 	sbp_free_request(req);
 }
 
-static u32 sbp_sess_get_index(struct se_session *se_sess)
-{
-	return 0;
-}
-
 static int sbp_write_pending(struct se_cmd *se_cmd)
 {
 	struct sbp_target_request *req = container_of(se_cmd,
@@ -2314,7 +2309,6 @@ static ssize_t sbp_tpg_attrib_max_logins_per_lun_store(struct config_item *item,
 	.tpg_check_prod_mode_write_protect = sbp_check_false,
 	.tpg_get_inst_index		= sbp_tpg_get_inst_index,
 	.release_cmd			= sbp_release_cmd,
-	.sess_get_index			= sbp_sess_get_index,
 	.write_pending			= sbp_write_pending,
 	.set_default_node_attributes	= sbp_set_default_node_attrs,
 	.get_cmd_state			= sbp_get_cmd_state,
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index 7e21b87..dcb981d 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -399,10 +399,6 @@ static int target_fabric_tf_ops_check(const struct target_core_fabric_ops *tfo)
 		pr_err("Missing tfo->release_cmd()\n");
 		return -EINVAL;
 	}
-	if (!tfo->sess_get_index) {
-		pr_err("Missing tfo->sess_get_index()\n");
-		return -EINVAL;
-	}
 	if (!tfo->write_pending) {
 		pr_err("Missing tfo->write_pending()\n");
 		return -EINVAL;
diff --git a/drivers/target/target_core_stat.c b/drivers/target/target_core_stat.c
index cc9c966..562532f 100644
--- a/drivers/target/target_core_stat.c
+++ b/drivers/target/target_core_stat.c
@@ -1264,7 +1264,6 @@ static ssize_t target_stat_iport_indx_show(struct config_item *item,
 	struct se_lun_acl *lacl = iport_to_lacl(item);
 	struct se_node_acl *nacl = lacl->se_lun_nacl;
 	struct se_session *se_sess;
-	struct se_portal_group *tpg;
 	ssize_t ret;
 
 	spin_lock_irq(&nacl->nacl_sess_lock);
@@ -1274,10 +1273,8 @@ static ssize_t target_stat_iport_indx_show(struct config_item *item,
 		return -ENODEV;
 	}
 
-	tpg = nacl->se_tpg;
 	/* scsiAttIntrPortIndex */
-	ret = snprintf(page, PAGE_SIZE, "%u\n",
-			tpg->se_tpg_tfo->sess_get_index(se_sess));
+	ret = snprintf(page, PAGE_SIZE, "%u\n", se_sess->sid);
 	spin_unlock_irq(&nacl->nacl_sess_lock);
 	return ret;
 }
diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c
index 7983554..a0e9970 100644
--- a/drivers/target/tcm_fc/tfc_conf.c
+++ b/drivers/target/tcm_fc/tfc_conf.c
@@ -427,7 +427,6 @@ static u32 ft_tpg_get_inst_index(struct se_portal_group *se_tpg)
 	.release_cmd =			ft_release_cmd,
 	.close_session =		ft_sess_close,
 	.init_session =			ft_sess_init,
-	.sess_get_index =		ft_sess_get_index,
 	.write_pending =		ft_write_pending,
 	.set_default_node_attributes =	ft_set_default_node_attr,
 	.get_cmd_state =		ft_get_cmd_state,
diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c
index 7357c38..4a55b6f 100644
--- a/drivers/target/tcm_fc/tfc_sess.c
+++ b/drivers/target/tcm_fc/tfc_sess.c
@@ -330,13 +330,6 @@ void ft_sess_close(struct se_session *se_sess)
 	synchronize_rcu();		/* let transport deregister happen */
 }
 
-u32 ft_sess_get_index(struct se_session *se_sess)
-{
-	struct ft_sess *sess = se_sess->fabric_sess_ptr;
-
-	return sess->port_id;	/* XXX TBD probably not what is needed */
-}
-
 u32 ft_sess_get_port_name(struct se_session *se_sess,
 			  unsigned char *buf, u32 len)
 {
diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c
index eab61c6..1724432 100644
--- a/drivers/usb/gadget/function/f_tcm.c
+++ b/drivers/usb/gadget/function/f_tcm.c
@@ -1287,11 +1287,6 @@ static void usbg_release_cmd(struct se_cmd *se_cmd)
 	target_free_tag(se_sess, se_cmd);
 }
 
-static u32 usbg_sess_get_index(struct se_session *se_sess)
-{
-	return 0;
-}
-
 static void usbg_set_default_node_attrs(struct se_node_acl *nacl)
 {
 }
@@ -1720,7 +1715,6 @@ static int usbg_check_stop_free(struct se_cmd *se_cmd)
 	.tpg_check_prod_mode_write_protect = usbg_check_false,
 	.tpg_get_inst_index		= usbg_tpg_get_inst_index,
 	.release_cmd			= usbg_release_cmd,
-	.sess_get_index			= usbg_sess_get_index,
 	.write_pending			= usbg_send_write_request,
 	.set_default_node_attributes	= usbg_set_default_node_attrs,
 	.get_cmd_state			= usbg_get_cmd_state,
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 51392ab..40fb1c7 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -340,11 +340,6 @@ static void vhost_scsi_release_cmd(struct se_cmd *se_cmd)
 	target_free_tag(se_sess, se_cmd);
 }
 
-static u32 vhost_scsi_sess_get_index(struct se_session *se_sess)
-{
-	return 0;
-}
-
 static int vhost_scsi_write_pending(struct se_cmd *se_cmd)
 {
 	/* Go ahead and process the write immediately */
@@ -2308,7 +2303,6 @@ static void vhost_scsi_drop_tport(struct se_wwn *wwn)
 	.tpg_get_inst_index		= vhost_scsi_tpg_get_inst_index,
 	.release_cmd			= vhost_scsi_release_cmd,
 	.check_stop_free		= vhost_scsi_check_stop_free,
-	.sess_get_index			= vhost_scsi_sess_get_index,
 	.write_pending			= vhost_scsi_write_pending,
 	.set_default_node_attributes	= vhost_scsi_set_default_node_attrs,
 	.get_cmd_state			= vhost_scsi_get_cmd_state,
diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
index 1d8c0c2..f183ec3 100644
--- a/drivers/xen/xen-scsiback.c
+++ b/drivers/xen/xen-scsiback.c
@@ -1391,11 +1391,6 @@ static void scsiback_release_cmd(struct se_cmd *se_cmd)
 	target_free_tag(se_cmd->se_sess, se_cmd);
 }
 
-static u32 scsiback_sess_get_index(struct se_session *se_sess)
-{
-	return 0;
-}
-
 static int scsiback_write_pending(struct se_cmd *se_cmd)
 {
 	/* Go ahead and process the write immediately */
@@ -1829,7 +1824,6 @@ static int scsiback_check_false(struct se_portal_group *se_tpg)
 	.tpg_get_inst_index		= scsiback_tpg_get_inst_index,
 	.check_stop_free		= scsiback_check_stop_free,
 	.release_cmd			= scsiback_release_cmd,
-	.sess_get_index			= scsiback_sess_get_index,
 	.write_pending			= scsiback_write_pending,
 	.set_default_node_attributes	= scsiback_set_default_node_attrs,
 	.get_cmd_state			= scsiback_get_cmd_state,
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
index 509edcf..335ef7d0 100644
--- a/include/target/target_core_fabric.h
+++ b/include/target/target_core_fabric.h
@@ -66,7 +66,6 @@ struct target_core_fabric_ops {
 	int (*check_stop_free)(struct se_cmd *);
 	void (*release_cmd)(struct se_cmd *);
 	void (*close_session)(struct se_session *);
-	u32 (*sess_get_index)(struct se_session *);
 	int (*write_pending)(struct se_cmd *);
 	void (*set_default_node_attributes)(struct se_node_acl *);
 	int (*get_cmd_state)(struct se_cmd *);
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [RFC PATCH 12/12] target: drop sess_get_index
@ 2020-04-20 19:14   ` Mike Christie
  0 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-20 19:14 UTC (permalink / raw)
  To: jsmart2021, bvanassche, bstroesser, martin.petersen, linux-scsi,
	target-devel
  Cc: Mike Christie

LIO now handles session id allocation so drop the callout.

Signed-off-by: Mike Christie <mchristi@redhat.com>
---
 drivers/infiniband/ulp/srpt/ib_srpt.c        | 15 ---------------
 drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c     |  6 ------
 drivers/scsi/qla2xxx/tcm_qla2xxx.c           |  7 -------
 drivers/target/iscsi/iscsi_target_configfs.c |  6 ------
 drivers/target/loopback/tcm_loop.c           |  6 ------
 drivers/target/sbp/sbp_target.c              |  6 ------
 drivers/target/target_core_configfs.c        |  4 ----
 drivers/target/target_core_stat.c            |  5 +----
 drivers/target/tcm_fc/tfc_conf.c             |  1 -
 drivers/target/tcm_fc/tfc_sess.c             |  7 -------
 drivers/usb/gadget/function/f_tcm.c          |  6 ------
 drivers/vhost/scsi.c                         |  6 ------
 drivers/xen/xen-scsiback.c                   |  6 ------
 include/target/target_core_fabric.h          |  1 -
 14 files changed, 1 insertion(+), 81 deletions(-)

diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
index 59a6b9b..87330bb 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -3356,20 +3356,6 @@ static void srpt_close_session(struct se_session *se_sess)
 	srpt_disconnect_ch_sync(ch);
 }
 
-/**
- * srpt_sess_get_index - return the value of scsiAttIntrPortIndex (SCSI-MIB)
- * @se_sess: SCSI target session.
- *
- * A quote from RFC 4455 (SCSI-MIB) about this MIB object:
- * This object represents an arbitrary integer used to uniquely identify a
- * particular attached remote initiator port to a particular SCSI target port
- * within a particular SCSI target device within a particular SCSI instance.
- */
-static u32 srpt_sess_get_index(struct se_session *se_sess)
-{
-	return 0;
-}
-
 static void srpt_set_default_node_attrs(struct se_node_acl *nacl)
 {
 }
@@ -3846,7 +3832,6 @@ static ssize_t srpt_wwn_version_show(struct config_item *item, char *buf)
 	.release_cmd			= srpt_release_cmd,
 	.check_stop_free		= srpt_check_stop_free,
 	.close_session			= srpt_close_session,
-	.sess_get_index			= srpt_sess_get_index,
 	.write_pending			= srpt_write_pending,
 	.set_default_node_attributes	= srpt_set_default_node_attrs,
 	.get_cmd_state			= srpt_get_tcm_cmd_state,
diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
index 23ffcd8..42b3c83 100644
--- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
+++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
@@ -3744,11 +3744,6 @@ static void ibmvscsis_release_cmd(struct se_cmd *se_cmd)
 	spin_unlock_bh(&vscsi->intr_lock);
 }
 
-static u32 ibmvscsis_sess_get_index(struct se_session *se_sess)
-{
-	return 0;
-}
-
 static int ibmvscsis_write_pending(struct se_cmd *se_cmd)
 {
 	struct ibmvscsis_cmd *cmd = container_of(se_cmd, struct ibmvscsis_cmd,
@@ -4039,7 +4034,6 @@ static ssize_t ibmvscsis_tpg_enable_store(struct config_item *item,
 	.tpg_get_inst_index		= ibmvscsis_tpg_get_inst_index,
 	.check_stop_free		= ibmvscsis_check_stop_free,
 	.release_cmd			= ibmvscsis_release_cmd,
-	.sess_get_index			= ibmvscsis_sess_get_index,
 	.write_pending			= ibmvscsis_write_pending,
 	.set_default_node_attributes	= ibmvscsis_set_default_node_attrs,
 	.get_cmd_state			= ibmvscsis_get_cmd_state,
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index d864d13..a60dc89 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -354,11 +354,6 @@ static void tcm_qla2xxx_close_session(struct se_session *se_sess)
 	tcm_qla2xxx_put_sess(sess);
 }
 
-static u32 tcm_qla2xxx_sess_get_index(struct se_session *se_sess)
-{
-	return 0;
-}
-
 static int tcm_qla2xxx_write_pending(struct se_cmd *se_cmd)
 {
 	struct qla_tgt_cmd *cmd = container_of(se_cmd,
@@ -1833,7 +1828,6 @@ static ssize_t tcm_qla2xxx_wwn_version_show(struct config_item *item,
 	.release_cmd			= tcm_qla2xxx_release_cmd,
 	.close_session			= tcm_qla2xxx_close_session,
 	.init_session			= tcm_qla2xxx_init_session,
-	.sess_get_index			= tcm_qla2xxx_sess_get_index,
 	.write_pending			= tcm_qla2xxx_write_pending,
 	.set_default_node_attributes	= tcm_qla2xxx_set_default_node_attrs,
 	.get_cmd_state			= tcm_qla2xxx_get_cmd_state,
@@ -1873,7 +1867,6 @@ static ssize_t tcm_qla2xxx_wwn_version_show(struct config_item *item,
 	.release_cmd			= tcm_qla2xxx_release_cmd,
 	.close_session			= tcm_qla2xxx_close_session,
 	.init_session			= tcm_qla2xxx_init_session,
-	.sess_get_index			= tcm_qla2xxx_sess_get_index,
 	.write_pending			= tcm_qla2xxx_write_pending,
 	.set_default_node_attributes	= tcm_qla2xxx_set_default_node_attrs,
 	.get_cmd_state			= tcm_qla2xxx_get_cmd_state,
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c
index c40cff1..0b98245 100644
--- a/drivers/target/iscsi/iscsi_target_configfs.c
+++ b/drivers/target/iscsi/iscsi_target_configfs.c
@@ -1342,11 +1342,6 @@ static int iscsi_get_cmd_state(struct se_cmd *se_cmd)
 	return cmd->i_state;
 }
 
-static u32 lio_sess_get_index(struct se_session *se_sess)
-{
-	return se_sess->sid;
-}
-
 static int lio_queue_data_in(struct se_cmd *se_cmd)
 {
 	struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
@@ -1527,7 +1522,6 @@ static void lio_release_cmd(struct se_cmd *se_cmd)
 	.check_stop_free		= lio_check_stop_free,
 	.release_cmd			= lio_release_cmd,
 	.close_session			= lio_tpg_close_session,
-	.sess_get_index			= lio_sess_get_index,
 	.write_pending			= lio_write_pending,
 	.set_default_node_attributes	= lio_set_default_node_attributes,
 	.get_cmd_state			= iscsi_get_cmd_state,
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index 7025b7e..1d92c36 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -512,11 +512,6 @@ static u32 tcm_loop_get_inst_index(struct se_portal_group *se_tpg)
 	return 1;
 }
 
-static u32 tcm_loop_sess_get_index(struct se_session *se_sess)
-{
-	return 1;
-}
-
 static void tcm_loop_set_default_node_attributes(struct se_node_acl *se_acl)
 {
 	return;
@@ -1156,7 +1151,6 @@ static ssize_t tcm_loop_wwn_version_show(struct config_item *item, char *page)
 	.tpg_get_inst_index		= tcm_loop_get_inst_index,
 	.check_stop_free		= tcm_loop_check_stop_free,
 	.release_cmd			= tcm_loop_release_cmd,
-	.sess_get_index			= tcm_loop_sess_get_index,
 	.write_pending			= tcm_loop_write_pending,
 	.set_default_node_attributes	= tcm_loop_set_default_node_attributes,
 	.get_cmd_state			= tcm_loop_get_cmd_state,
diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c
index 20f8b3b..a3d868b 100644
--- a/drivers/target/sbp/sbp_target.c
+++ b/drivers/target/sbp/sbp_target.c
@@ -1713,11 +1713,6 @@ static void sbp_release_cmd(struct se_cmd *se_cmd)
 	sbp_free_request(req);
 }
 
-static u32 sbp_sess_get_index(struct se_session *se_sess)
-{
-	return 0;
-}
-
 static int sbp_write_pending(struct se_cmd *se_cmd)
 {
 	struct sbp_target_request *req = container_of(se_cmd,
@@ -2314,7 +2309,6 @@ static ssize_t sbp_tpg_attrib_max_logins_per_lun_store(struct config_item *item,
 	.tpg_check_prod_mode_write_protect = sbp_check_false,
 	.tpg_get_inst_index		= sbp_tpg_get_inst_index,
 	.release_cmd			= sbp_release_cmd,
-	.sess_get_index			= sbp_sess_get_index,
 	.write_pending			= sbp_write_pending,
 	.set_default_node_attributes	= sbp_set_default_node_attrs,
 	.get_cmd_state			= sbp_get_cmd_state,
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index 7e21b87..dcb981d 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -399,10 +399,6 @@ static int target_fabric_tf_ops_check(const struct target_core_fabric_ops *tfo)
 		pr_err("Missing tfo->release_cmd()\n");
 		return -EINVAL;
 	}
-	if (!tfo->sess_get_index) {
-		pr_err("Missing tfo->sess_get_index()\n");
-		return -EINVAL;
-	}
 	if (!tfo->write_pending) {
 		pr_err("Missing tfo->write_pending()\n");
 		return -EINVAL;
diff --git a/drivers/target/target_core_stat.c b/drivers/target/target_core_stat.c
index cc9c966..562532f 100644
--- a/drivers/target/target_core_stat.c
+++ b/drivers/target/target_core_stat.c
@@ -1264,7 +1264,6 @@ static ssize_t target_stat_iport_indx_show(struct config_item *item,
 	struct se_lun_acl *lacl = iport_to_lacl(item);
 	struct se_node_acl *nacl = lacl->se_lun_nacl;
 	struct se_session *se_sess;
-	struct se_portal_group *tpg;
 	ssize_t ret;
 
 	spin_lock_irq(&nacl->nacl_sess_lock);
@@ -1274,10 +1273,8 @@ static ssize_t target_stat_iport_indx_show(struct config_item *item,
 		return -ENODEV;
 	}
 
-	tpg = nacl->se_tpg;
 	/* scsiAttIntrPortIndex */
-	ret = snprintf(page, PAGE_SIZE, "%u\n",
-			tpg->se_tpg_tfo->sess_get_index(se_sess));
+	ret = snprintf(page, PAGE_SIZE, "%u\n", se_sess->sid);
 	spin_unlock_irq(&nacl->nacl_sess_lock);
 	return ret;
 }
diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c
index 7983554..a0e9970 100644
--- a/drivers/target/tcm_fc/tfc_conf.c
+++ b/drivers/target/tcm_fc/tfc_conf.c
@@ -427,7 +427,6 @@ static u32 ft_tpg_get_inst_index(struct se_portal_group *se_tpg)
 	.release_cmd =			ft_release_cmd,
 	.close_session =		ft_sess_close,
 	.init_session =			ft_sess_init,
-	.sess_get_index =		ft_sess_get_index,
 	.write_pending =		ft_write_pending,
 	.set_default_node_attributes =	ft_set_default_node_attr,
 	.get_cmd_state =		ft_get_cmd_state,
diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c
index 7357c38..4a55b6f 100644
--- a/drivers/target/tcm_fc/tfc_sess.c
+++ b/drivers/target/tcm_fc/tfc_sess.c
@@ -330,13 +330,6 @@ void ft_sess_close(struct se_session *se_sess)
 	synchronize_rcu();		/* let transport deregister happen */
 }
 
-u32 ft_sess_get_index(struct se_session *se_sess)
-{
-	struct ft_sess *sess = se_sess->fabric_sess_ptr;
-
-	return sess->port_id;	/* XXX TBD probably not what is needed */
-}
-
 u32 ft_sess_get_port_name(struct se_session *se_sess,
 			  unsigned char *buf, u32 len)
 {
diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c
index eab61c6..1724432 100644
--- a/drivers/usb/gadget/function/f_tcm.c
+++ b/drivers/usb/gadget/function/f_tcm.c
@@ -1287,11 +1287,6 @@ static void usbg_release_cmd(struct se_cmd *se_cmd)
 	target_free_tag(se_sess, se_cmd);
 }
 
-static u32 usbg_sess_get_index(struct se_session *se_sess)
-{
-	return 0;
-}
-
 static void usbg_set_default_node_attrs(struct se_node_acl *nacl)
 {
 }
@@ -1720,7 +1715,6 @@ static int usbg_check_stop_free(struct se_cmd *se_cmd)
 	.tpg_check_prod_mode_write_protect = usbg_check_false,
 	.tpg_get_inst_index		= usbg_tpg_get_inst_index,
 	.release_cmd			= usbg_release_cmd,
-	.sess_get_index			= usbg_sess_get_index,
 	.write_pending			= usbg_send_write_request,
 	.set_default_node_attributes	= usbg_set_default_node_attrs,
 	.get_cmd_state			= usbg_get_cmd_state,
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 51392ab..40fb1c7 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -340,11 +340,6 @@ static void vhost_scsi_release_cmd(struct se_cmd *se_cmd)
 	target_free_tag(se_sess, se_cmd);
 }
 
-static u32 vhost_scsi_sess_get_index(struct se_session *se_sess)
-{
-	return 0;
-}
-
 static int vhost_scsi_write_pending(struct se_cmd *se_cmd)
 {
 	/* Go ahead and process the write immediately */
@@ -2308,7 +2303,6 @@ static void vhost_scsi_drop_tport(struct se_wwn *wwn)
 	.tpg_get_inst_index		= vhost_scsi_tpg_get_inst_index,
 	.release_cmd			= vhost_scsi_release_cmd,
 	.check_stop_free		= vhost_scsi_check_stop_free,
-	.sess_get_index			= vhost_scsi_sess_get_index,
 	.write_pending			= vhost_scsi_write_pending,
 	.set_default_node_attributes	= vhost_scsi_set_default_node_attrs,
 	.get_cmd_state			= vhost_scsi_get_cmd_state,
diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
index 1d8c0c2..f183ec3 100644
--- a/drivers/xen/xen-scsiback.c
+++ b/drivers/xen/xen-scsiback.c
@@ -1391,11 +1391,6 @@ static void scsiback_release_cmd(struct se_cmd *se_cmd)
 	target_free_tag(se_cmd->se_sess, se_cmd);
 }
 
-static u32 scsiback_sess_get_index(struct se_session *se_sess)
-{
-	return 0;
-}
-
 static int scsiback_write_pending(struct se_cmd *se_cmd)
 {
 	/* Go ahead and process the write immediately */
@@ -1829,7 +1824,6 @@ static int scsiback_check_false(struct se_portal_group *se_tpg)
 	.tpg_get_inst_index		= scsiback_tpg_get_inst_index,
 	.check_stop_free		= scsiback_check_stop_free,
 	.release_cmd			= scsiback_release_cmd,
-	.sess_get_index			= scsiback_sess_get_index,
 	.write_pending			= scsiback_write_pending,
 	.set_default_node_attributes	= scsiback_set_default_node_attrs,
 	.get_cmd_state			= scsiback_get_cmd_state,
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
index 509edcf..335ef7d0 100644
--- a/include/target/target_core_fabric.h
+++ b/include/target/target_core_fabric.h
@@ -66,7 +66,6 @@ struct target_core_fabric_ops {
 	int (*check_stop_free)(struct se_cmd *);
 	void (*release_cmd)(struct se_cmd *);
 	void (*close_session)(struct se_session *);
-	u32 (*sess_get_index)(struct se_session *);
 	int (*write_pending)(struct se_cmd *);
 	void (*set_default_node_attributes)(struct se_node_acl *);
 	int (*get_cmd_state)(struct se_cmd *);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [RFC PATCH 02/12] target: separate acl name from port ids
  2020-04-20 19:14   ` Mike Christie
@ 2020-04-21 14:49     ` Bodo Stroesser
  -1 siblings, 0 replies; 38+ messages in thread
From: Bodo Stroesser @ 2020-04-21 14:49 UTC (permalink / raw)
  To: Mike Christie, jsmart2021, bvanassche, martin.petersen,
	linux-scsi, target-devel

I'm wondering, whether the 'format' element of the new t10_transport_id
structure is useful:

- It is used for iSCSI only, but is a common field for all protocols.

- In iSCSI, if format is 0 then session_id is NULL, and if format is
   not 0 then session_id is not NULL. So session_id can be used for the
   same purpose.

- I think it is a bug that tcm_loop and vhost claim to run iSCSI
   protocol, but don't deliver an ISID. They e.g. could use the "Random"
   format for the ISID, which starts with byte 0x80 followed by 3 random
   bytes and 2 further bytes denoting the session.

Removing the format element would of course mean to not add the "format"
session attribute later. (The "session_id" attribute doesn't even check
format, but uses session_id as argument to "%s" in snprintf even if it
is NULL).


On 04/20/20 21:14, Mike Christie wrote:
> To handle features like PGRs in userspace we need the entire iniaitor
> port id. For iscsi that is defined as the initiator name plus the
> session identifier. The session id is hidden from users, because
> its internal to the drivers, so this patch separates the acl name
> from the SCSI port ids.
> 
> This will then allow other drivers like SRP to use different values
> like the port id or src address for the ACL, but then use the port
> id for transport ID checks in target_core_fabric.c.
> 
> This will also be used to export the initiator info in the session's
> sysfs dir in the last patches, so tools like tcmu-runner can rebuild
> its session state used when handling PGR commands.
> 
> Signed-off-by: Mike Christie <mchristi@redhat.com>
> ---
>   drivers/infiniband/ulp/srpt/ib_srpt.c    | 13 +++--
>   drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c |  9 +++-
>   drivers/scsi/qla2xxx/tcm_qla2xxx.c       |  8 ++-
>   drivers/target/loopback/tcm_loop.c       | 24 ++++++++-
>   drivers/target/sbp/sbp_target.c          |  9 +++-
>   drivers/target/target_core_fabric_lib.c  | 87 ++++++++++++++++++++++++++++++++
>   drivers/target/target_core_internal.h    |  1 +
>   drivers/target/target_core_transport.c   | 22 +++++---
>   drivers/target/tcm_fc/tfc_sess.c         | 10 +++-
>   drivers/usb/gadget/function/f_tcm.c      | 11 +++-
>   drivers/vhost/scsi.c                     | 25 +++++++--
>   drivers/xen/xen-scsiback.c               | 28 ++++++++--
>   include/target/target_core_base.h        | 24 +++++++++
>   include/target/target_core_fabric.h      |  3 +-
>   14 files changed, 245 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
> index 9855274..caeb32e 100644
> --- a/drivers/infiniband/ulp/srpt/ib_srpt.c
> +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
> @@ -2144,6 +2144,7 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev,
>   			    const char *src_addr)
>   {
>   	struct srpt_port *sport = &sdev->port[port_num - 1];
> +	struct t10_transport_id tpid;
>   	struct srpt_nexus *nexus;
>   	struct srp_login_rsp *rsp = NULL;
>   	struct srp_login_rej *rej = NULL;
> @@ -2314,13 +2315,17 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev,
>   	tag_num = ch->rq_size;
>   	tag_size = 1; /* ib_srpt does not use se_sess->sess_cmd_map */
>   
> +	memset(&tpid, 0, sizeof(tpid));
> +	tpid.proto = SCSI_PROTOCOL_SRP;
> +	tpid.srp.port_id = i_port_id + 2;
> +
>   	mutex_lock(&sport->port_guid_id.mutex);
>   	list_for_each_entry(stpg, &sport->port_guid_id.tpg_list, entry) {
>   		if (!IS_ERR_OR_NULL(ch->sess))
>   			break;
>   		ch->sess = target_setup_session(&stpg->tpg, tag_num,
>   						tag_size, TARGET_PROT_NORMAL,
> -						ch->sess_name, ch, NULL);
> +						&tpid, ch->sess_name, ch, NULL);
>   	}
>   	mutex_unlock(&sport->port_guid_id.mutex);
>   
> @@ -2329,14 +2334,14 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev,
>   		if (!IS_ERR_OR_NULL(ch->sess))
>   			break;
>   		ch->sess = target_setup_session(&stpg->tpg, tag_num,
> -					tag_size, TARGET_PROT_NORMAL, i_port_id,
> -					ch, NULL);
> +					tag_size, TARGET_PROT_NORMAL, &tpid,
> +					i_port_id, ch, NULL);
>   		if (!IS_ERR_OR_NULL(ch->sess))
>   			break;
>   		/* Retry without leading "0x" */
>   		ch->sess = target_setup_session(&stpg->tpg, tag_num,
>   						tag_size, TARGET_PROT_NORMAL,
> -						i_port_id + 2, ch, NULL);
> +						&tpid, i_port_id + 2, ch, NULL);
>   	}
>   	mutex_unlock(&sport->port_gid_id.mutex);
>   
> diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
> index d9e94e8..dba9ec0 100644
> --- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
> +++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
> @@ -2208,6 +2208,7 @@ static int ibmvscsis_make_nexus(struct ibmvscsis_tport *tport)
>   {
>   	char *name = tport->tport_name;
>   	struct ibmvscsis_nexus *nexus;
> +	struct t10_transport_id tpid;
>   	struct scsi_info *vscsi = container_of(tport, struct scsi_info, tport);
>   	int rc;
>   
> @@ -2222,9 +2223,13 @@ static int ibmvscsis_make_nexus(struct ibmvscsis_tport *tport)
>   		return -ENOMEM;
>   	}
>   
> +	memset(&tpid, 0, sizeof(tpid));
> +	tpid.proto = SCSI_PROTOCOL_SRP;
> +	tpid.srp.port_id = name;
> +
>   	nexus->se_sess = target_setup_session(&tport->se_tpg, 0, 0,
> -					      TARGET_PROT_NORMAL, name, nexus,
> -					      NULL);
> +					      TARGET_PROT_NORMAL, &tpid, name,
> +					      nexus, NULL);
>   	if (IS_ERR(nexus->se_sess)) {
>   		rc = PTR_ERR(nexus->se_sess);
>   		goto transport_init_fail;
> diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
> index abe7f79..42a4025 100644
> --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
> +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
> @@ -1428,6 +1428,7 @@ static int tcm_qla2xxx_check_initiator_node_acl(
>   {
>   	struct qla_hw_data *ha = vha->hw;
>   	struct tcm_qla2xxx_lport *lport;
> +	struct t10_transport_id tpid;
>   	struct tcm_qla2xxx_tpg *tpg;
>   	struct se_session *se_sess;
>   	unsigned char port_name[36];
> @@ -1454,13 +1455,18 @@ static int tcm_qla2xxx_check_initiator_node_acl(
>   	 */
>   	memset(&port_name, 0, 36);
>   	snprintf(port_name, sizeof(port_name), "%8phC", fc_wwpn);
> +
> +	memset(&tpid, 0, sizeof(tpid));
> +	tpid.proto = SCSI_PROTOCOL_FCP;
> +	tpid.fcp.port_name = port_name;
> +
>   	/*
>   	 * Locate our struct se_node_acl either from an explict NodeACL created
>   	 * via ConfigFS, or via running in TPG demo mode.
>   	 */
>   	se_sess = target_setup_session(&tpg->se_tpg, num_tags,
>   				       sizeof(struct qla_tgt_cmd),
> -				       TARGET_PROT_ALL, port_name,
> +				       TARGET_PROT_ALL, &tpid, port_name,
>   				       qlat_sess, tcm_qla2xxx_session_cb);
>   	if (IS_ERR(se_sess))
>   		return PTR_ERR(se_sess);
> diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
> index 3305b47..7593a53 100644
> --- a/drivers/target/loopback/tcm_loop.c
> +++ b/drivers/target/loopback/tcm_loop.c
> @@ -725,10 +725,11 @@ static int tcm_loop_alloc_sess_cb(struct se_portal_group *se_tpg,
>   
>   static int tcm_loop_make_nexus(
>   	struct tcm_loop_tpg *tl_tpg,
> -	const char *name)
> +	char *name)
>   {
>   	struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
>   	struct tcm_loop_nexus *tl_nexus;
> +	struct t10_transport_id tpid;
>   	int ret;
>   
>   	if (tl_tpg->tl_nexus) {
> @@ -736,13 +737,32 @@ static int tcm_loop_make_nexus(
>   		return -EEXIST;
>   	}
>   
> +	memset(&tpid, 0, sizeof(tpid));
> +	tpid.proto = tl_hba->tl_proto_id;
> +
> +	switch (tpid.proto) {
> +	case SCSI_PROTOCOL_SAS:
> +		tpid.sas.addr = name;
> +		break;
> +	case SCSI_PROTOCOL_FCP:
> +		tpid.fcp.port_name = name;
> +		break;
> +	case SCSI_PROTOCOL_ISCSI:
> +		/* we only support format=0 */
> +		tpid.iscsi.name = name;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
>   	tl_nexus = kzalloc(sizeof(*tl_nexus), GFP_KERNEL);
>   	if (!tl_nexus)
>   		return -ENOMEM;
>   
>   	tl_nexus->se_sess = target_setup_session(&tl_tpg->tl_se_tpg, 0, 0,
>   					TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS,
> -					name, tl_nexus, tcm_loop_alloc_sess_cb);
> +					&tpid, name, tl_nexus,
> +					tcm_loop_alloc_sess_cb);
>   	if (IS_ERR(tl_nexus->se_sess)) {
>   		ret = PTR_ERR(tl_nexus->se_sess);
>   		kfree(tl_nexus);
> diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c
> index e4a9b9f..9a3121d 100644
> --- a/drivers/target/sbp/sbp_target.c
> +++ b/drivers/target/sbp/sbp_target.c
> @@ -181,6 +181,7 @@ static struct sbp_session *sbp_session_create(
>   		struct sbp_tpg *tpg,
>   		u64 guid)
>   {
> +	struct t10_transport_id tpid;
>   	struct sbp_session *sess;
>   	int ret;
>   	char guid_str[17];
> @@ -196,10 +197,14 @@ static struct sbp_session *sbp_session_create(
>   	INIT_DELAYED_WORK(&sess->maint_work, session_maintenance_work);
>   	sess->guid = guid;
>   
> +	memset(&tpid, 0, sizeof(tpid));
> +	tpid.proto = SCSI_PROTOCOL_SBP;
> +	tpid.sbp.name = guid_str;
> +
>   	sess->se_sess = target_setup_session(&tpg->se_tpg, 128,
>   					     sizeof(struct sbp_target_request),
> -					     TARGET_PROT_NORMAL, guid_str,
> -					     sess, NULL);
> +					     TARGET_PROT_NORMAL, &tpid,
> +					     guid_str, sess, NULL);
>   	if (IS_ERR(sess->se_sess)) {
>   		pr_err("failed to init se_session\n");
>   		ret = PTR_ERR(sess->se_sess);
> diff --git a/drivers/target/target_core_fabric_lib.c b/drivers/target/target_core_fabric_lib.c
> index 6b4b354..39b0e5e 100644
> --- a/drivers/target/target_core_fabric_lib.c
> +++ b/drivers/target/target_core_fabric_lib.c
> @@ -421,3 +421,90 @@ const char *target_parse_pr_out_transport_id(struct se_portal_group *tpg,
>   	*out_tid_len = 24;
>   	return buf + offset;
>   }
> +
> +struct t10_transport_id *target_cp_transport_id(struct t10_transport_id *src)
> +{
> +	struct t10_transport_id *dst;
> +
> +	dst = kzalloc(sizeof(*dst), GFP_KERNEL);
> +	if (!dst)
> +		return NULL;
> +	dst->format = src->format;
> +	dst->proto = src->proto;
> +
> +	switch (src->proto) {
> +	case SCSI_PROTOCOL_FCP:
> +		dst->fcp.port_name = kstrdup(src->fcp.port_name, GFP_KERNEL);
> +		if (!dst->fcp.port_name)
> +			goto free_tpid;
> +		break;
> +	case SCSI_PROTOCOL_SBP:
> +		dst->sbp.name = kstrdup(src->sbp.name, GFP_KERNEL);
> +		if (!dst->sbp.name)
> +			goto free_tpid;
> +		break;
> +	case SCSI_PROTOCOL_SRP:
> +		dst->srp.port_id = kstrdup(src->srp.port_id, GFP_KERNEL);
> +		if (!dst->srp.port_id)
> +			goto free_tpid;
> +		break;
> +	case SCSI_PROTOCOL_SAS:
> +		dst->sas.addr = kstrdup(src->sas.addr, GFP_KERNEL);
> +		if (!dst->sas.addr)
> +			goto free_tpid;
> +		break;
> +	case SCSI_PROTOCOL_ISCSI:
> +		dst->iscsi.name = kstrdup(src->iscsi.name, GFP_KERNEL);
> +		if (!dst->iscsi.name)
> +			goto free_tpid;
> +
> +		if (src->format) {
> +			dst->iscsi.session_id = kstrdup(src->iscsi.session_id,
> +							GFP_KERNEL);
> +			if (!dst->iscsi.session_id) {
> +				kfree(dst->iscsi.name);
> +				goto free_tpid;
> +			}
> +		}
> +		break;
> +	default:
> +		pr_err("Unknown proto_id: 0x%02x\n", src->proto);
> +		return NULL;
> +	}
> +
> +	return dst;
> +
> +free_tpid:
> +	kfree(dst);
> +	return NULL;
> +}
> +EXPORT_SYMBOL(target_cp_transport_id);
> +
> +void target_free_transport_id(struct t10_transport_id *tpid)
> +{
> +	if (!tpid)
> +		return;
> +
> +	switch (tpid->proto) {
> +	case SCSI_PROTOCOL_FCP:
> +		kfree(tpid->fcp.port_name);
> +		break;
> +	case SCSI_PROTOCOL_SBP:
> +		kfree(tpid->sbp.name);
> +		break;
> +	case SCSI_PROTOCOL_SRP:
> +		kfree(tpid->srp.port_id);
> +		break;
> +	case SCSI_PROTOCOL_SAS:
> +		kfree(tpid->sas.addr);
> +		break;
> +	case SCSI_PROTOCOL_ISCSI:
> +		kfree(tpid->iscsi.name);
> +		kfree(tpid->iscsi.session_id);
> +		break;
> +	default:
> +		pr_err("Unknown proto_id: 0x%02x\n", tpid->proto);
> +		return;
> +	}
> +	kfree(tpid);
> +}
> diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h
> index 8533444..5e016aa 100644
> --- a/drivers/target/target_core_internal.h
> +++ b/drivers/target/target_core_internal.h
> @@ -104,6 +104,7 @@ int	target_get_pr_transport_id(struct se_node_acl *nacl,
>   		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);
> +void target_free_transport_id(struct t10_transport_id *tpid);
>   
>   /* target_core_hba.c */
>   struct se_hba *core_alloc_hba(const char *, u32, u32);
> diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
> index 0ae9e60..adf4a84 100644
> --- a/drivers/target/target_core_transport.c
> +++ b/drivers/target/target_core_transport.c
> @@ -416,12 +416,13 @@ void transport_register_session(
>   struct se_session *
>   target_setup_session(struct se_portal_group *tpg,
>   		     unsigned int tag_num, unsigned int tag_size,
> -		     enum target_prot_op prot_op,
> +		     enum target_prot_op prot_op, struct t10_transport_id *tpid,
>   		     const char *initiatorname, void *private,
>   		     int (*callback)(struct se_portal_group *,
>   				     struct se_session *, void *))
>   {
>   	struct se_session *sess;
> +	int rc;
>   
>   	/*
>   	 * If the fabric driver is using percpu-ida based pre allocation
> @@ -435,6 +436,12 @@ struct se_session *
>   	if (IS_ERR(sess))
>   		return sess;
>   
> +	sess->tpid = target_cp_transport_id(tpid);
> +	if (!sess->tpid) {
> +		rc = -ENOMEM;
> +		goto free_sess;
> +	}
> +
>   	sess->se_node_acl = core_tpg_check_initiator_node_acl(tpg,
>   					(unsigned char *)initiatorname);
>   	if (!sess->se_node_acl) {
> @@ -446,15 +453,17 @@ struct se_session *
>   	 * required before transport_register_session().
>   	 */
>   	if (callback != NULL) {
> -		int rc = callback(tpg, sess, private);
> -		if (rc) {
> -			transport_free_session(sess);
> -			return ERR_PTR(rc);
> -		}
> +		rc = callback(tpg, sess, private);
> +		if (rc)
> +			goto free_sess;
>   	}
>   
>   	transport_register_session(tpg, sess->se_node_acl, sess, private);
>   	return sess;
> +
> +free_sess:
> +	transport_free_session(sess);
> +	return ERR_PTR(rc);
>   }
>   EXPORT_SYMBOL(target_setup_session);
>   
> @@ -579,6 +588,7 @@ void transport_free_session(struct se_session *se_sess)
>   		sbitmap_queue_free(&se_sess->sess_tag_pool);
>   		kvfree(se_sess->sess_cmd_map);
>   	}
> +	target_free_transport_id(se_sess->tpid);
>   	percpu_ref_exit(&se_sess->cmd_count);
>   	kmem_cache_free(se_sess_cache, se_sess);
>   }
> diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c
> index 4fd6a1d..f261756 100644
> --- a/drivers/target/tcm_fc/tfc_sess.c
> +++ b/drivers/target/tcm_fc/tfc_sess.c
> @@ -208,6 +208,7 @@ static struct ft_sess *ft_sess_create(struct ft_tport *tport, u32 port_id,
>   				      struct fc_rport_priv *rdata)
>   {
>   	struct se_portal_group *se_tpg = &tport->tpg->se_tpg;
> +	struct t10_transport_id tpid;
>   	struct ft_sess *sess;
>   	struct hlist_head *head;
>   	unsigned char initiatorname[TRANSPORT_IQN_LEN];
> @@ -227,10 +228,15 @@ static struct ft_sess *ft_sess_create(struct ft_tport *tport, u32 port_id,
>   	sess->tport = tport;
>   	sess->port_id = port_id;
>   
> +	memset(&tpid, 0, sizeof(tpid));
> +	tpid.proto = SCSI_PROTOCOL_FCP;
> +	tpid.fcp.port_name = &initiatorname[0];
> +
>   	sess->se_sess = target_setup_session(se_tpg, TCM_FC_DEFAULT_TAGS,
>   					     sizeof(struct ft_cmd),
> -					     TARGET_PROT_NORMAL, &initiatorname[0],
> -					     sess, ft_sess_alloc_cb);
> +					     TARGET_PROT_NORMAL, &tpid,
> +					     &initiatorname[0], sess,
> +					     ft_sess_alloc_cb);
>   	if (IS_ERR(sess->se_sess)) {
>   		int rc = PTR_ERR(sess->se_sess);
>   		kfree(sess);
> diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c
> index 3650493..e282eb9 100644
> --- a/drivers/usb/gadget/function/f_tcm.c
> +++ b/drivers/usb/gadget/function/f_tcm.c
> @@ -1564,6 +1564,7 @@ static int usbg_alloc_sess_cb(struct se_portal_group *se_tpg,
>   static int tcm_usbg_make_nexus(struct usbg_tpg *tpg, char *name)
>   {
>   	struct tcm_usbg_nexus *tv_nexus;
> +	struct t10_transport_id tpid;
>   	int ret = 0;
>   
>   	mutex_lock(&tpg->tpg_mutex);
> @@ -1579,11 +1580,17 @@ static int tcm_usbg_make_nexus(struct usbg_tpg *tpg, char *name)
>   		goto out_unlock;
>   	}
>   
> +	memset(&tpid, 0, sizeof(tpid));
> +	tpid.proto = tpg->se_tpg.proto_id;
> +	/* SPC does not assign a proto id for USB-SCSI so we use SAS naming */
> +	tpid.sas.addr = name;
> +
>   	tv_nexus->tvn_se_sess = target_setup_session(&tpg->se_tpg,
>   						     USB_G_DEFAULT_SESSION_TAGS,
>   						     sizeof(struct usbg_cmd),
> -						     TARGET_PROT_NORMAL, name,
> -						     tv_nexus, usbg_alloc_sess_cb);
> +						     TARGET_PROT_NORMAL, &tpid,
> +						     name, tv_nexus,
> +						     usbg_alloc_sess_cb);
>   	if (IS_ERR(tv_nexus->tvn_se_sess)) {
>   #define MAKE_NEXUS_MSG "core_tpg_check_initiator_node_acl() failed for %s\n"
>   		pr_debug(MAKE_NEXUS_MSG, name);
> diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
> index 0b949a1..bc377ee 100644
> --- a/drivers/vhost/scsi.c
> +++ b/drivers/vhost/scsi.c
> @@ -1937,10 +1937,10 @@ static int vhost_scsi_nexus_cb(struct se_portal_group *se_tpg,
>   	return -ENOMEM;
>   }
>   
> -static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg,
> -				const char *name)
> +static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg, char *name)
>   {
>   	struct vhost_scsi_nexus *tv_nexus;
> +	struct t10_transport_id tpid;
>   
>   	mutex_lock(&tpg->tv_tpg_mutex);
>   	if (tpg->tpg_nexus) {
> @@ -1949,6 +1949,25 @@ static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg,
>   		return -EEXIST;
>   	}
>   
> +	memset(&tpid, 0, sizeof(tpid));
> +	tpid.proto = tpg->se_tpg.proto_id;
> +
> +	switch (tpid.proto) {
> +	case SCSI_PROTOCOL_SAS:
> +		tpid.sas.addr = name;
> +		break;
> +	case SCSI_PROTOCOL_FCP:
> +		tpid.fcp.port_name = name;
> +		break;
> +	case SCSI_PROTOCOL_ISCSI:
> +		/* we only support format=0 */
> +		tpid.iscsi.name = name;
> +		break;
> +	default:
> +		mutex_unlock(&tpg->tv_tpg_mutex);
> +		return -EINVAL;
> +	}
> +
>   	tv_nexus = kzalloc(sizeof(*tv_nexus), GFP_KERNEL);
>   	if (!tv_nexus) {
>   		mutex_unlock(&tpg->tv_tpg_mutex);
> @@ -1964,7 +1983,7 @@ static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg,
>   					VHOST_SCSI_DEFAULT_TAGS,
>   					sizeof(struct vhost_scsi_cmd),
>   					TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS,
> -					(unsigned char *)name, tv_nexus,
> +					&tpid, (unsigned char *)name, tv_nexus,
>   					vhost_scsi_nexus_cb);
>   	if (IS_ERR(tv_nexus->tvn_se_sess)) {
>   		mutex_unlock(&tpg->tv_tpg_mutex);
> diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
> index ba0942e..0855a77f 100644
> --- a/drivers/xen/xen-scsiback.c
> +++ b/drivers/xen/xen-scsiback.c
> @@ -1507,10 +1507,10 @@ static int scsiback_alloc_sess_cb(struct se_portal_group *se_tpg,
>   	return 0;
>   }
>   
> -static int scsiback_make_nexus(struct scsiback_tpg *tpg,
> -				const char *name)
> +static int scsiback_make_nexus(struct scsiback_tpg *tpg, char *name)
>   {
>   	struct scsiback_nexus *tv_nexus;
> +	struct t10_transport_id tpid;
>   	int ret = 0;
>   
>   	mutex_lock(&tpg->tv_tpg_mutex);
> @@ -1520,6 +1520,25 @@ static int scsiback_make_nexus(struct scsiback_tpg *tpg,
>   		goto out_unlock;
>   	}
>   
> +	memset(&tpid, 0, sizeof(tpid));
> +	tpid.proto = tpg->se_tpg.proto_id;
> +
> +	switch (tpid.proto) {
> +	case SCSI_PROTOCOL_SAS:
> +		tpid.sas.addr = name;
> +		break;
> +	case SCSI_PROTOCOL_FCP:
> +		tpid.fcp.port_name = name;
> +		break;
> +	case SCSI_PROTOCOL_ISCSI:
> +		/* we only support format=0 */
> +		tpid.iscsi.name = name;
> +		break;
> +	default:
> +		ret =-EINVAL;
> +		goto out_unlock;
> +	}
> +
>   	tv_nexus = kzalloc(sizeof(struct scsiback_nexus), GFP_KERNEL);
>   	if (!tv_nexus) {
>   		ret = -ENOMEM;
> @@ -1529,8 +1548,9 @@ static int scsiback_make_nexus(struct scsiback_tpg *tpg,
>   	tv_nexus->tvn_se_sess = target_setup_session(&tpg->se_tpg,
>   						     VSCSI_DEFAULT_SESSION_TAGS,
>   						     sizeof(struct vscsibk_pend),
> -						     TARGET_PROT_NORMAL, name,
> -						     tv_nexus, scsiback_alloc_sess_cb);
> +						     TARGET_PROT_NORMAL, &tpid,
> +						     name, tv_nexus,
> +						     scsiback_alloc_sess_cb);
>   	if (IS_ERR(tv_nexus->tvn_se_sess)) {
>   		kfree(tv_nexus);
>   		ret = -ENOMEM;
> diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
> index 1728e88..cd440ea 100644
> --- a/include/target/target_core_base.h
> +++ b/include/target/target_core_base.h
> @@ -333,6 +333,29 @@ struct t10_wwn {
>   	struct list_head t10_vpd_list;
>   };
>   
> +struct t10_transport_id {
> +	union {
> +		struct {
> +			char *port_name;
> +		} fcp;
> +		struct {
> +			char *addr;
> +		} sas;
> +		struct {
> +			char *name;
> +		} sbp;
> +		struct {
> +			char *port_id;
> +		} srp;
> +		struct {
> +			char *name;
> +			char *session_id;
> +		} iscsi;
> +	};
> +	u8 format;
> +	u8 proto;
> +};
> +
>   struct t10_pr_registration {
>   	/* Used for fabrics that contain WWN+ISID */
>   #define PR_REG_ISID_LEN				16
> @@ -605,6 +628,7 @@ static inline struct se_node_acl *fabric_stat_to_nacl(struct config_item *item)
>   struct se_session {
>   	unsigned		sess_tearing_down:1;
>   	u64			sess_bin_isid;
> +	struct t10_transport_id	*tpid;
>   	enum target_prot_op	sup_prot_ops;
>   	enum target_prot_type	sess_prot_type;
>   	struct se_node_acl	*se_node_acl;
> diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
> index 063f133..6b8a6bc 100644
> --- a/include/target/target_core_fabric.h
> +++ b/include/target/target_core_fabric.h
> @@ -125,9 +125,10 @@ struct target_core_fabric_ops {
>   int target_depend_item(struct config_item *item);
>   void target_undepend_item(struct config_item *item);
>   
> +struct t10_transport_id *target_cp_transport_id(struct t10_transport_id *);
>   struct se_session *target_setup_session(struct se_portal_group *,
>   		unsigned int, unsigned int, enum target_prot_op prot_op,
> -		const char *, void *,
> +		struct t10_transport_id *, const char *, void *,
>   		int (*callback)(struct se_portal_group *,
>   				struct se_session *, void *));
>   void target_remove_session(struct se_session *);
> 

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [RFC PATCH 02/12] target: separate acl name from port ids
@ 2020-04-21 14:49     ` Bodo Stroesser
  0 siblings, 0 replies; 38+ messages in thread
From: Bodo Stroesser @ 2020-04-21 14:49 UTC (permalink / raw)
  To: Mike Christie, jsmart2021, bvanassche, martin.petersen,
	linux-scsi, target-devel

I'm wondering, whether the 'format' element of the new t10_transport_id
structure is useful:

- It is used for iSCSI only, but is a common field for all protocols.

- In iSCSI, if format is 0 then session_id is NULL, and if format is
   not 0 then session_id is not NULL. So session_id can be used for the
   same purpose.

- I think it is a bug that tcm_loop and vhost claim to run iSCSI
   protocol, but don't deliver an ISID. They e.g. could use the "Random"
   format for the ISID, which starts with byte 0x80 followed by 3 random
   bytes and 2 further bytes denoting the session.

Removing the format element would of course mean to not add the "format"
session attribute later. (The "session_id" attribute doesn't even check
format, but uses session_id as argument to "%s" in snprintf even if it
is NULL).


On 04/20/20 21:14, Mike Christie wrote:
> To handle features like PGRs in userspace we need the entire iniaitor
> port id. For iscsi that is defined as the initiator name plus the
> session identifier. The session id is hidden from users, because
> its internal to the drivers, so this patch separates the acl name
> from the SCSI port ids.
> 
> This will then allow other drivers like SRP to use different values
> like the port id or src address for the ACL, but then use the port
> id for transport ID checks in target_core_fabric.c.
> 
> This will also be used to export the initiator info in the session's
> sysfs dir in the last patches, so tools like tcmu-runner can rebuild
> its session state used when handling PGR commands.
> 
> Signed-off-by: Mike Christie <mchristi@redhat.com>
> ---
>   drivers/infiniband/ulp/srpt/ib_srpt.c    | 13 +++--
>   drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c |  9 +++-
>   drivers/scsi/qla2xxx/tcm_qla2xxx.c       |  8 ++-
>   drivers/target/loopback/tcm_loop.c       | 24 ++++++++-
>   drivers/target/sbp/sbp_target.c          |  9 +++-
>   drivers/target/target_core_fabric_lib.c  | 87 ++++++++++++++++++++++++++++++++
>   drivers/target/target_core_internal.h    |  1 +
>   drivers/target/target_core_transport.c   | 22 +++++---
>   drivers/target/tcm_fc/tfc_sess.c         | 10 +++-
>   drivers/usb/gadget/function/f_tcm.c      | 11 +++-
>   drivers/vhost/scsi.c                     | 25 +++++++--
>   drivers/xen/xen-scsiback.c               | 28 ++++++++--
>   include/target/target_core_base.h        | 24 +++++++++
>   include/target/target_core_fabric.h      |  3 +-
>   14 files changed, 245 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
> index 9855274..caeb32e 100644
> --- a/drivers/infiniband/ulp/srpt/ib_srpt.c
> +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
> @@ -2144,6 +2144,7 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev,
>   			    const char *src_addr)
>   {
>   	struct srpt_port *sport = &sdev->port[port_num - 1];
> +	struct t10_transport_id tpid;
>   	struct srpt_nexus *nexus;
>   	struct srp_login_rsp *rsp = NULL;
>   	struct srp_login_rej *rej = NULL;
> @@ -2314,13 +2315,17 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev,
>   	tag_num = ch->rq_size;
>   	tag_size = 1; /* ib_srpt does not use se_sess->sess_cmd_map */
>   
> +	memset(&tpid, 0, sizeof(tpid));
> +	tpid.proto = SCSI_PROTOCOL_SRP;
> +	tpid.srp.port_id = i_port_id + 2;
> +
>   	mutex_lock(&sport->port_guid_id.mutex);
>   	list_for_each_entry(stpg, &sport->port_guid_id.tpg_list, entry) {
>   		if (!IS_ERR_OR_NULL(ch->sess))
>   			break;
>   		ch->sess = target_setup_session(&stpg->tpg, tag_num,
>   						tag_size, TARGET_PROT_NORMAL,
> -						ch->sess_name, ch, NULL);
> +						&tpid, ch->sess_name, ch, NULL);
>   	}
>   	mutex_unlock(&sport->port_guid_id.mutex);
>   
> @@ -2329,14 +2334,14 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev,
>   		if (!IS_ERR_OR_NULL(ch->sess))
>   			break;
>   		ch->sess = target_setup_session(&stpg->tpg, tag_num,
> -					tag_size, TARGET_PROT_NORMAL, i_port_id,
> -					ch, NULL);
> +					tag_size, TARGET_PROT_NORMAL, &tpid,
> +					i_port_id, ch, NULL);
>   		if (!IS_ERR_OR_NULL(ch->sess))
>   			break;
>   		/* Retry without leading "0x" */
>   		ch->sess = target_setup_session(&stpg->tpg, tag_num,
>   						tag_size, TARGET_PROT_NORMAL,
> -						i_port_id + 2, ch, NULL);
> +						&tpid, i_port_id + 2, ch, NULL);
>   	}
>   	mutex_unlock(&sport->port_gid_id.mutex);
>   
> diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
> index d9e94e8..dba9ec0 100644
> --- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
> +++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
> @@ -2208,6 +2208,7 @@ static int ibmvscsis_make_nexus(struct ibmvscsis_tport *tport)
>   {
>   	char *name = tport->tport_name;
>   	struct ibmvscsis_nexus *nexus;
> +	struct t10_transport_id tpid;
>   	struct scsi_info *vscsi = container_of(tport, struct scsi_info, tport);
>   	int rc;
>   
> @@ -2222,9 +2223,13 @@ static int ibmvscsis_make_nexus(struct ibmvscsis_tport *tport)
>   		return -ENOMEM;
>   	}
>   
> +	memset(&tpid, 0, sizeof(tpid));
> +	tpid.proto = SCSI_PROTOCOL_SRP;
> +	tpid.srp.port_id = name;
> +
>   	nexus->se_sess = target_setup_session(&tport->se_tpg, 0, 0,
> -					      TARGET_PROT_NORMAL, name, nexus,
> -					      NULL);
> +					      TARGET_PROT_NORMAL, &tpid, name,
> +					      nexus, NULL);
>   	if (IS_ERR(nexus->se_sess)) {
>   		rc = PTR_ERR(nexus->se_sess);
>   		goto transport_init_fail;
> diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
> index abe7f79..42a4025 100644
> --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
> +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
> @@ -1428,6 +1428,7 @@ static int tcm_qla2xxx_check_initiator_node_acl(
>   {
>   	struct qla_hw_data *ha = vha->hw;
>   	struct tcm_qla2xxx_lport *lport;
> +	struct t10_transport_id tpid;
>   	struct tcm_qla2xxx_tpg *tpg;
>   	struct se_session *se_sess;
>   	unsigned char port_name[36];
> @@ -1454,13 +1455,18 @@ static int tcm_qla2xxx_check_initiator_node_acl(
>   	 */
>   	memset(&port_name, 0, 36);
>   	snprintf(port_name, sizeof(port_name), "%8phC", fc_wwpn);
> +
> +	memset(&tpid, 0, sizeof(tpid));
> +	tpid.proto = SCSI_PROTOCOL_FCP;
> +	tpid.fcp.port_name = port_name;
> +
>   	/*
>   	 * Locate our struct se_node_acl either from an explict NodeACL created
>   	 * via ConfigFS, or via running in TPG demo mode.
>   	 */
>   	se_sess = target_setup_session(&tpg->se_tpg, num_tags,
>   				       sizeof(struct qla_tgt_cmd),
> -				       TARGET_PROT_ALL, port_name,
> +				       TARGET_PROT_ALL, &tpid, port_name,
>   				       qlat_sess, tcm_qla2xxx_session_cb);
>   	if (IS_ERR(se_sess))
>   		return PTR_ERR(se_sess);
> diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
> index 3305b47..7593a53 100644
> --- a/drivers/target/loopback/tcm_loop.c
> +++ b/drivers/target/loopback/tcm_loop.c
> @@ -725,10 +725,11 @@ static int tcm_loop_alloc_sess_cb(struct se_portal_group *se_tpg,
>   
>   static int tcm_loop_make_nexus(
>   	struct tcm_loop_tpg *tl_tpg,
> -	const char *name)
> +	char *name)
>   {
>   	struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
>   	struct tcm_loop_nexus *tl_nexus;
> +	struct t10_transport_id tpid;
>   	int ret;
>   
>   	if (tl_tpg->tl_nexus) {
> @@ -736,13 +737,32 @@ static int tcm_loop_make_nexus(
>   		return -EEXIST;
>   	}
>   
> +	memset(&tpid, 0, sizeof(tpid));
> +	tpid.proto = tl_hba->tl_proto_id;
> +
> +	switch (tpid.proto) {
> +	case SCSI_PROTOCOL_SAS:
> +		tpid.sas.addr = name;
> +		break;
> +	case SCSI_PROTOCOL_FCP:
> +		tpid.fcp.port_name = name;
> +		break;
> +	case SCSI_PROTOCOL_ISCSI:
> +		/* we only support format=0 */
> +		tpid.iscsi.name = name;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
>   	tl_nexus = kzalloc(sizeof(*tl_nexus), GFP_KERNEL);
>   	if (!tl_nexus)
>   		return -ENOMEM;
>   
>   	tl_nexus->se_sess = target_setup_session(&tl_tpg->tl_se_tpg, 0, 0,
>   					TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS,
> -					name, tl_nexus, tcm_loop_alloc_sess_cb);
> +					&tpid, name, tl_nexus,
> +					tcm_loop_alloc_sess_cb);
>   	if (IS_ERR(tl_nexus->se_sess)) {
>   		ret = PTR_ERR(tl_nexus->se_sess);
>   		kfree(tl_nexus);
> diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c
> index e4a9b9f..9a3121d 100644
> --- a/drivers/target/sbp/sbp_target.c
> +++ b/drivers/target/sbp/sbp_target.c
> @@ -181,6 +181,7 @@ static struct sbp_session *sbp_session_create(
>   		struct sbp_tpg *tpg,
>   		u64 guid)
>   {
> +	struct t10_transport_id tpid;
>   	struct sbp_session *sess;
>   	int ret;
>   	char guid_str[17];
> @@ -196,10 +197,14 @@ static struct sbp_session *sbp_session_create(
>   	INIT_DELAYED_WORK(&sess->maint_work, session_maintenance_work);
>   	sess->guid = guid;
>   
> +	memset(&tpid, 0, sizeof(tpid));
> +	tpid.proto = SCSI_PROTOCOL_SBP;
> +	tpid.sbp.name = guid_str;
> +
>   	sess->se_sess = target_setup_session(&tpg->se_tpg, 128,
>   					     sizeof(struct sbp_target_request),
> -					     TARGET_PROT_NORMAL, guid_str,
> -					     sess, NULL);
> +					     TARGET_PROT_NORMAL, &tpid,
> +					     guid_str, sess, NULL);
>   	if (IS_ERR(sess->se_sess)) {
>   		pr_err("failed to init se_session\n");
>   		ret = PTR_ERR(sess->se_sess);
> diff --git a/drivers/target/target_core_fabric_lib.c b/drivers/target/target_core_fabric_lib.c
> index 6b4b354..39b0e5e 100644
> --- a/drivers/target/target_core_fabric_lib.c
> +++ b/drivers/target/target_core_fabric_lib.c
> @@ -421,3 +421,90 @@ const char *target_parse_pr_out_transport_id(struct se_portal_group *tpg,
>   	*out_tid_len = 24;
>   	return buf + offset;
>   }
> +
> +struct t10_transport_id *target_cp_transport_id(struct t10_transport_id *src)
> +{
> +	struct t10_transport_id *dst;
> +
> +	dst = kzalloc(sizeof(*dst), GFP_KERNEL);
> +	if (!dst)
> +		return NULL;
> +	dst->format = src->format;
> +	dst->proto = src->proto;
> +
> +	switch (src->proto) {
> +	case SCSI_PROTOCOL_FCP:
> +		dst->fcp.port_name = kstrdup(src->fcp.port_name, GFP_KERNEL);
> +		if (!dst->fcp.port_name)
> +			goto free_tpid;
> +		break;
> +	case SCSI_PROTOCOL_SBP:
> +		dst->sbp.name = kstrdup(src->sbp.name, GFP_KERNEL);
> +		if (!dst->sbp.name)
> +			goto free_tpid;
> +		break;
> +	case SCSI_PROTOCOL_SRP:
> +		dst->srp.port_id = kstrdup(src->srp.port_id, GFP_KERNEL);
> +		if (!dst->srp.port_id)
> +			goto free_tpid;
> +		break;
> +	case SCSI_PROTOCOL_SAS:
> +		dst->sas.addr = kstrdup(src->sas.addr, GFP_KERNEL);
> +		if (!dst->sas.addr)
> +			goto free_tpid;
> +		break;
> +	case SCSI_PROTOCOL_ISCSI:
> +		dst->iscsi.name = kstrdup(src->iscsi.name, GFP_KERNEL);
> +		if (!dst->iscsi.name)
> +			goto free_tpid;
> +
> +		if (src->format) {
> +			dst->iscsi.session_id = kstrdup(src->iscsi.session_id,
> +							GFP_KERNEL);
> +			if (!dst->iscsi.session_id) {
> +				kfree(dst->iscsi.name);
> +				goto free_tpid;
> +			}
> +		}
> +		break;
> +	default:
> +		pr_err("Unknown proto_id: 0x%02x\n", src->proto);
> +		return NULL;
> +	}
> +
> +	return dst;
> +
> +free_tpid:
> +	kfree(dst);
> +	return NULL;
> +}
> +EXPORT_SYMBOL(target_cp_transport_id);
> +
> +void target_free_transport_id(struct t10_transport_id *tpid)
> +{
> +	if (!tpid)
> +		return;
> +
> +	switch (tpid->proto) {
> +	case SCSI_PROTOCOL_FCP:
> +		kfree(tpid->fcp.port_name);
> +		break;
> +	case SCSI_PROTOCOL_SBP:
> +		kfree(tpid->sbp.name);
> +		break;
> +	case SCSI_PROTOCOL_SRP:
> +		kfree(tpid->srp.port_id);
> +		break;
> +	case SCSI_PROTOCOL_SAS:
> +		kfree(tpid->sas.addr);
> +		break;
> +	case SCSI_PROTOCOL_ISCSI:
> +		kfree(tpid->iscsi.name);
> +		kfree(tpid->iscsi.session_id);
> +		break;
> +	default:
> +		pr_err("Unknown proto_id: 0x%02x\n", tpid->proto);
> +		return;
> +	}
> +	kfree(tpid);
> +}
> diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h
> index 8533444..5e016aa 100644
> --- a/drivers/target/target_core_internal.h
> +++ b/drivers/target/target_core_internal.h
> @@ -104,6 +104,7 @@ int	target_get_pr_transport_id(struct se_node_acl *nacl,
>   		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);
> +void target_free_transport_id(struct t10_transport_id *tpid);
>   
>   /* target_core_hba.c */
>   struct se_hba *core_alloc_hba(const char *, u32, u32);
> diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
> index 0ae9e60..adf4a84 100644
> --- a/drivers/target/target_core_transport.c
> +++ b/drivers/target/target_core_transport.c
> @@ -416,12 +416,13 @@ void transport_register_session(
>   struct se_session *
>   target_setup_session(struct se_portal_group *tpg,
>   		     unsigned int tag_num, unsigned int tag_size,
> -		     enum target_prot_op prot_op,
> +		     enum target_prot_op prot_op, struct t10_transport_id *tpid,
>   		     const char *initiatorname, void *private,
>   		     int (*callback)(struct se_portal_group *,
>   				     struct se_session *, void *))
>   {
>   	struct se_session *sess;
> +	int rc;
>   
>   	/*
>   	 * If the fabric driver is using percpu-ida based pre allocation
> @@ -435,6 +436,12 @@ struct se_session *
>   	if (IS_ERR(sess))
>   		return sess;
>   
> +	sess->tpid = target_cp_transport_id(tpid);
> +	if (!sess->tpid) {
> +		rc = -ENOMEM;
> +		goto free_sess;
> +	}
> +
>   	sess->se_node_acl = core_tpg_check_initiator_node_acl(tpg,
>   					(unsigned char *)initiatorname);
>   	if (!sess->se_node_acl) {
> @@ -446,15 +453,17 @@ struct se_session *
>   	 * required before transport_register_session().
>   	 */
>   	if (callback != NULL) {
> -		int rc = callback(tpg, sess, private);
> -		if (rc) {
> -			transport_free_session(sess);
> -			return ERR_PTR(rc);
> -		}
> +		rc = callback(tpg, sess, private);
> +		if (rc)
> +			goto free_sess;
>   	}
>   
>   	transport_register_session(tpg, sess->se_node_acl, sess, private);
>   	return sess;
> +
> +free_sess:
> +	transport_free_session(sess);
> +	return ERR_PTR(rc);
>   }
>   EXPORT_SYMBOL(target_setup_session);
>   
> @@ -579,6 +588,7 @@ void transport_free_session(struct se_session *se_sess)
>   		sbitmap_queue_free(&se_sess->sess_tag_pool);
>   		kvfree(se_sess->sess_cmd_map);
>   	}
> +	target_free_transport_id(se_sess->tpid);
>   	percpu_ref_exit(&se_sess->cmd_count);
>   	kmem_cache_free(se_sess_cache, se_sess);
>   }
> diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c
> index 4fd6a1d..f261756 100644
> --- a/drivers/target/tcm_fc/tfc_sess.c
> +++ b/drivers/target/tcm_fc/tfc_sess.c
> @@ -208,6 +208,7 @@ static struct ft_sess *ft_sess_create(struct ft_tport *tport, u32 port_id,
>   				      struct fc_rport_priv *rdata)
>   {
>   	struct se_portal_group *se_tpg = &tport->tpg->se_tpg;
> +	struct t10_transport_id tpid;
>   	struct ft_sess *sess;
>   	struct hlist_head *head;
>   	unsigned char initiatorname[TRANSPORT_IQN_LEN];
> @@ -227,10 +228,15 @@ static struct ft_sess *ft_sess_create(struct ft_tport *tport, u32 port_id,
>   	sess->tport = tport;
>   	sess->port_id = port_id;
>   
> +	memset(&tpid, 0, sizeof(tpid));
> +	tpid.proto = SCSI_PROTOCOL_FCP;
> +	tpid.fcp.port_name = &initiatorname[0];
> +
>   	sess->se_sess = target_setup_session(se_tpg, TCM_FC_DEFAULT_TAGS,
>   					     sizeof(struct ft_cmd),
> -					     TARGET_PROT_NORMAL, &initiatorname[0],
> -					     sess, ft_sess_alloc_cb);
> +					     TARGET_PROT_NORMAL, &tpid,
> +					     &initiatorname[0], sess,
> +					     ft_sess_alloc_cb);
>   	if (IS_ERR(sess->se_sess)) {
>   		int rc = PTR_ERR(sess->se_sess);
>   		kfree(sess);
> diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c
> index 3650493..e282eb9 100644
> --- a/drivers/usb/gadget/function/f_tcm.c
> +++ b/drivers/usb/gadget/function/f_tcm.c
> @@ -1564,6 +1564,7 @@ static int usbg_alloc_sess_cb(struct se_portal_group *se_tpg,
>   static int tcm_usbg_make_nexus(struct usbg_tpg *tpg, char *name)
>   {
>   	struct tcm_usbg_nexus *tv_nexus;
> +	struct t10_transport_id tpid;
>   	int ret = 0;
>   
>   	mutex_lock(&tpg->tpg_mutex);
> @@ -1579,11 +1580,17 @@ static int tcm_usbg_make_nexus(struct usbg_tpg *tpg, char *name)
>   		goto out_unlock;
>   	}
>   
> +	memset(&tpid, 0, sizeof(tpid));
> +	tpid.proto = tpg->se_tpg.proto_id;
> +	/* SPC does not assign a proto id for USB-SCSI so we use SAS naming */
> +	tpid.sas.addr = name;
> +
>   	tv_nexus->tvn_se_sess = target_setup_session(&tpg->se_tpg,
>   						     USB_G_DEFAULT_SESSION_TAGS,
>   						     sizeof(struct usbg_cmd),
> -						     TARGET_PROT_NORMAL, name,
> -						     tv_nexus, usbg_alloc_sess_cb);
> +						     TARGET_PROT_NORMAL, &tpid,
> +						     name, tv_nexus,
> +						     usbg_alloc_sess_cb);
>   	if (IS_ERR(tv_nexus->tvn_se_sess)) {
>   #define MAKE_NEXUS_MSG "core_tpg_check_initiator_node_acl() failed for %s\n"
>   		pr_debug(MAKE_NEXUS_MSG, name);
> diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
> index 0b949a1..bc377ee 100644
> --- a/drivers/vhost/scsi.c
> +++ b/drivers/vhost/scsi.c
> @@ -1937,10 +1937,10 @@ static int vhost_scsi_nexus_cb(struct se_portal_group *se_tpg,
>   	return -ENOMEM;
>   }
>   
> -static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg,
> -				const char *name)
> +static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg, char *name)
>   {
>   	struct vhost_scsi_nexus *tv_nexus;
> +	struct t10_transport_id tpid;
>   
>   	mutex_lock(&tpg->tv_tpg_mutex);
>   	if (tpg->tpg_nexus) {
> @@ -1949,6 +1949,25 @@ static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg,
>   		return -EEXIST;
>   	}
>   
> +	memset(&tpid, 0, sizeof(tpid));
> +	tpid.proto = tpg->se_tpg.proto_id;
> +
> +	switch (tpid.proto) {
> +	case SCSI_PROTOCOL_SAS:
> +		tpid.sas.addr = name;
> +		break;
> +	case SCSI_PROTOCOL_FCP:
> +		tpid.fcp.port_name = name;
> +		break;
> +	case SCSI_PROTOCOL_ISCSI:
> +		/* we only support format=0 */
> +		tpid.iscsi.name = name;
> +		break;
> +	default:
> +		mutex_unlock(&tpg->tv_tpg_mutex);
> +		return -EINVAL;
> +	}
> +
>   	tv_nexus = kzalloc(sizeof(*tv_nexus), GFP_KERNEL);
>   	if (!tv_nexus) {
>   		mutex_unlock(&tpg->tv_tpg_mutex);
> @@ -1964,7 +1983,7 @@ static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg,
>   					VHOST_SCSI_DEFAULT_TAGS,
>   					sizeof(struct vhost_scsi_cmd),
>   					TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS,
> -					(unsigned char *)name, tv_nexus,
> +					&tpid, (unsigned char *)name, tv_nexus,
>   					vhost_scsi_nexus_cb);
>   	if (IS_ERR(tv_nexus->tvn_se_sess)) {
>   		mutex_unlock(&tpg->tv_tpg_mutex);
> diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
> index ba0942e..0855a77f 100644
> --- a/drivers/xen/xen-scsiback.c
> +++ b/drivers/xen/xen-scsiback.c
> @@ -1507,10 +1507,10 @@ static int scsiback_alloc_sess_cb(struct se_portal_group *se_tpg,
>   	return 0;
>   }
>   
> -static int scsiback_make_nexus(struct scsiback_tpg *tpg,
> -				const char *name)
> +static int scsiback_make_nexus(struct scsiback_tpg *tpg, char *name)
>   {
>   	struct scsiback_nexus *tv_nexus;
> +	struct t10_transport_id tpid;
>   	int ret = 0;
>   
>   	mutex_lock(&tpg->tv_tpg_mutex);
> @@ -1520,6 +1520,25 @@ static int scsiback_make_nexus(struct scsiback_tpg *tpg,
>   		goto out_unlock;
>   	}
>   
> +	memset(&tpid, 0, sizeof(tpid));
> +	tpid.proto = tpg->se_tpg.proto_id;
> +
> +	switch (tpid.proto) {
> +	case SCSI_PROTOCOL_SAS:
> +		tpid.sas.addr = name;
> +		break;
> +	case SCSI_PROTOCOL_FCP:
> +		tpid.fcp.port_name = name;
> +		break;
> +	case SCSI_PROTOCOL_ISCSI:
> +		/* we only support format=0 */
> +		tpid.iscsi.name = name;
> +		break;
> +	default:
> +		ret =-EINVAL;
> +		goto out_unlock;
> +	}
> +
>   	tv_nexus = kzalloc(sizeof(struct scsiback_nexus), GFP_KERNEL);
>   	if (!tv_nexus) {
>   		ret = -ENOMEM;
> @@ -1529,8 +1548,9 @@ static int scsiback_make_nexus(struct scsiback_tpg *tpg,
>   	tv_nexus->tvn_se_sess = target_setup_session(&tpg->se_tpg,
>   						     VSCSI_DEFAULT_SESSION_TAGS,
>   						     sizeof(struct vscsibk_pend),
> -						     TARGET_PROT_NORMAL, name,
> -						     tv_nexus, scsiback_alloc_sess_cb);
> +						     TARGET_PROT_NORMAL, &tpid,
> +						     name, tv_nexus,
> +						     scsiback_alloc_sess_cb);
>   	if (IS_ERR(tv_nexus->tvn_se_sess)) {
>   		kfree(tv_nexus);
>   		ret = -ENOMEM;
> diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
> index 1728e88..cd440ea 100644
> --- a/include/target/target_core_base.h
> +++ b/include/target/target_core_base.h
> @@ -333,6 +333,29 @@ struct t10_wwn {
>   	struct list_head t10_vpd_list;
>   };
>   
> +struct t10_transport_id {
> +	union {
> +		struct {
> +			char *port_name;
> +		} fcp;
> +		struct {
> +			char *addr;
> +		} sas;
> +		struct {
> +			char *name;
> +		} sbp;
> +		struct {
> +			char *port_id;
> +		} srp;
> +		struct {
> +			char *name;
> +			char *session_id;
> +		} iscsi;
> +	};
> +	u8 format;
> +	u8 proto;
> +};
> +
>   struct t10_pr_registration {
>   	/* Used for fabrics that contain WWN+ISID */
>   #define PR_REG_ISID_LEN				16
> @@ -605,6 +628,7 @@ static inline struct se_node_acl *fabric_stat_to_nacl(struct config_item *item)
>   struct se_session {
>   	unsigned		sess_tearing_down:1;
>   	u64			sess_bin_isid;
> +	struct t10_transport_id	*tpid;
>   	enum target_prot_op	sup_prot_ops;
>   	enum target_prot_type	sess_prot_type;
>   	struct se_node_acl	*se_node_acl;
> diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
> index 063f133..6b8a6bc 100644
> --- a/include/target/target_core_fabric.h
> +++ b/include/target/target_core_fabric.h
> @@ -125,9 +125,10 @@ struct target_core_fabric_ops {
>   int target_depend_item(struct config_item *item);
>   void target_undepend_item(struct config_item *item);
>   
> +struct t10_transport_id *target_cp_transport_id(struct t10_transport_id *);
>   struct se_session *target_setup_session(struct se_portal_group *,
>   		unsigned int, unsigned int, enum target_prot_op prot_op,
> -		const char *, void *,
> +		struct t10_transport_id *, const char *, void *,
>   		int (*callback)(struct se_portal_group *,
>   				struct se_session *, void *));
>   void target_remove_session(struct se_session *);
> 

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [RFC PATCH 04/12] target: use tpid in target_stat_iport_port_ident_show
  2020-04-20 19:14   ` Mike Christie
@ 2020-04-21 14:58     ` Bodo Stroesser
  -1 siblings, 0 replies; 38+ messages in thread
From: Bodo Stroesser @ 2020-04-21 14:58 UTC (permalink / raw)
  To: Mike Christie, jsmart2021, bvanassche, martin.petersen,
	linux-scsi, target-devel

On 04/20/20 21:14, Mike Christie wrote:
> diff --git a/drivers/target/target_core_stat.c b/drivers/target/target_core_stat.c
> index 237309d..cc9c966 100644
> --- a/drivers/target/target_core_stat.c
> +++ b/drivers/target/target_core_stat.c
> @@ -1309,8 +1309,8 @@ static ssize_t target_stat_iport_port_ident_show(struct config_item *item,
>   	struct se_node_acl *nacl = lacl->se_lun_nacl;
>   	struct se_session *se_sess;
>   	struct se_portal_group *tpg;
> +	char *session_id = NULL;
>   	ssize_t ret;
> -	unsigned char buf[64];
>   
>   	spin_lock_irq(&nacl->nacl_sess_lock);
>   	se_sess = nacl->nacl_sess;
> @@ -1319,13 +1319,13 @@ static ssize_t target_stat_iport_port_ident_show(struct config_item *item,
>   		return -ENODEV;
>   	}
>   
> +	session_id = transport_id_get_sid(se_sess->tpid);
> +	if (!session_id)
> +		session_id = "";
>   	tpg = nacl->se_tpg;
>   	/* scsiAttIntrPortName+scsiAttIntrPortIdentifier */
> -	memset(buf, 0, 64);
> -	if (tpg->se_tpg_tfo->sess_get_initiator_sid != NULL)
> -		tpg->se_tpg_tfo->sess_get_initiator_sid(se_sess, buf, 64);
> -
> -	ret = snprintf(page, PAGE_SIZE, "%s+i+%s\n", nacl->initiatorname, buf);
> +	ret = snprintf(page, PAGE_SIZE, "%s+i+%s\n", nacl->initiatorname,
> +		       session_id);
>   	spin_unlock_irq(&nacl->nacl_sess_lock);
>   	return ret;
>   }
> 
AFAICS, after the change "struct se_portal_group tpg" is no longer
necessary and can be removed completely.

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [RFC PATCH 04/12] target: use tpid in target_stat_iport_port_ident_show
@ 2020-04-21 14:58     ` Bodo Stroesser
  0 siblings, 0 replies; 38+ messages in thread
From: Bodo Stroesser @ 2020-04-21 14:58 UTC (permalink / raw)
  To: Mike Christie, jsmart2021, bvanassche, martin.petersen,
	linux-scsi, target-devel

On 04/20/20 21:14, Mike Christie wrote:
> diff --git a/drivers/target/target_core_stat.c b/drivers/target/target_core_stat.c
> index 237309d..cc9c966 100644
> --- a/drivers/target/target_core_stat.c
> +++ b/drivers/target/target_core_stat.c
> @@ -1309,8 +1309,8 @@ static ssize_t target_stat_iport_port_ident_show(struct config_item *item,
>   	struct se_node_acl *nacl = lacl->se_lun_nacl;
>   	struct se_session *se_sess;
>   	struct se_portal_group *tpg;
> +	char *session_id = NULL;
>   	ssize_t ret;
> -	unsigned char buf[64];
>   
>   	spin_lock_irq(&nacl->nacl_sess_lock);
>   	se_sess = nacl->nacl_sess;
> @@ -1319,13 +1319,13 @@ static ssize_t target_stat_iport_port_ident_show(struct config_item *item,
>   		return -ENODEV;
>   	}
>   
> +	session_id = transport_id_get_sid(se_sess->tpid);
> +	if (!session_id)
> +		session_id = "";
>   	tpg = nacl->se_tpg;
>   	/* scsiAttIntrPortName+scsiAttIntrPortIdentifier */
> -	memset(buf, 0, 64);
> -	if (tpg->se_tpg_tfo->sess_get_initiator_sid != NULL)
> -		tpg->se_tpg_tfo->sess_get_initiator_sid(se_sess, buf, 64);
> -
> -	ret = snprintf(page, PAGE_SIZE, "%s+i+%s\n", nacl->initiatorname, buf);
> +	ret = snprintf(page, PAGE_SIZE, "%s+i+%s\n", nacl->initiatorname,
> +		       session_id);
>   	spin_unlock_irq(&nacl->nacl_sess_lock);
>   	return ret;
>   }
> 
AFAICS, after the change "struct se_portal_group tpg" is no longer
necessary and can be removed completely.

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [RFC PATCH 07/12] target: add sysfs support
  2020-04-20 19:14   ` Mike Christie
@ 2020-04-21 15:48     ` Bodo Stroesser
  -1 siblings, 0 replies; 38+ messages in thread
From: Bodo Stroesser @ 2020-04-21 15:48 UTC (permalink / raw)
  To: Mike Christie, jsmart2021, bvanassche, martin.petersen,
	linux-scsi, target-devel

On 04/20/20 21:14, Mike Christie wrote:
> configfs does not work well when the kernel is initiating the creation
> of an object we want to export info for and the objects above/below it
> are created by the user. There are races/bugs like seen with this patch
> and the issue the original bug was trying to fix:
> 
> commit f19e4ed1e1edbfa3c9ccb9fed17759b7d6db24c6
> Author: Al Viro <viro@zeniv.linux.org.uk>
> Date:   Thu Aug 29 23:13:30 2019 -0400
> 
>      configfs_register_group() shouldn't be (and isn't) called in
> rmdirable parts
> 
> The problem is that for many drivers like qla2xxx, iscsi, etc, session
> creation is done by the kernel when there is a login initiated by an
> initiator, but we need a common way to export the systems sessions so
> tools like targetcli can report basic info like what initaitors are
> logged in and daemons like tcmu-runner can track sessions for load
> balancing and PGRs.
> 
> This patch begins to add a sysfs interface that will initially be used
> to export LIO's sessions. The general layout will mirror the lio
> configfs tree:
> 
> scsi_target /
> `-- $fabric_driver
>      `-- target_name
>          |-- tpgt_1
>          |   `-- sessions
>          `-- tpgt_2
>              `-- sessions
> 
> iscsi example:
> scsi_target /
> `-- iscsi
>      `-- iqn.1999-09.com.lio:tgt1
>          |-- tpgt_1
>          |   `-- sessions
>          `-- tpgt_2
>              `-- sessions
> 

Depending on future implementation of session info passthrough in tcmu,
it might be helpful to have an additional folder "sessions" directly
in scsi_target. This folder should contain one link for each session in
the lower "sessions" folders. The name of the link should be the same as
used for the session and the link should point to the session.

Example:

scsi_target
|- sessions
|  |- session-1 -> ../iscsi/iqn.1999-09.com.lio:tgt1/tpgt_2/session-1
|  `- session-2 -> ../iscsi/iqn.1999-09.com.lio:tgt1/tpgt_1/session-2
`- iscsi
    `- iqn.1999-09.com.lio:tgt1
       |- tpgt_1
       |  `- sessions
       |     `- session-2
       `- tpgt_2
          `- sessions
             `- session-1

The link can help to easily find the session for a given session_id and
also provides the wwn/tpg info for a session which together with the
info exposed by the session attributes completes the nexus info.

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [RFC PATCH 07/12] target: add sysfs support
@ 2020-04-21 15:48     ` Bodo Stroesser
  0 siblings, 0 replies; 38+ messages in thread
From: Bodo Stroesser @ 2020-04-21 15:48 UTC (permalink / raw)
  To: Mike Christie, jsmart2021, bvanassche, martin.petersen,
	linux-scsi, target-devel

On 04/20/20 21:14, Mike Christie wrote:
> configfs does not work well when the kernel is initiating the creation
> of an object we want to export info for and the objects above/below it
> are created by the user. There are races/bugs like seen with this patch
> and the issue the original bug was trying to fix:
> 
> commit f19e4ed1e1edbfa3c9ccb9fed17759b7d6db24c6
> Author: Al Viro <viro@zeniv.linux.org.uk>
> Date:   Thu Aug 29 23:13:30 2019 -0400
> 
>      configfs_register_group() shouldn't be (and isn't) called in
> rmdirable parts
> 
> The problem is that for many drivers like qla2xxx, iscsi, etc, session
> creation is done by the kernel when there is a login initiated by an
> initiator, but we need a common way to export the systems sessions so
> tools like targetcli can report basic info like what initaitors are
> logged in and daemons like tcmu-runner can track sessions for load
> balancing and PGRs.
> 
> This patch begins to add a sysfs interface that will initially be used
> to export LIO's sessions. The general layout will mirror the lio
> configfs tree:
> 
> scsi_target /
> `-- $fabric_driver
>      `-- target_name
>          |-- tpgt_1
>          |   `-- sessions
>          `-- tpgt_2
>              `-- sessions
> 
> iscsi example:
> scsi_target /
> `-- iscsi
>      `-- iqn.1999-09.com.lio:tgt1
>          |-- tpgt_1
>          |   `-- sessions
>          `-- tpgt_2
>              `-- sessions
> 

Depending on future implementation of session info passthrough in tcmu,
it might be helpful to have an additional folder "sessions" directly
in scsi_target. This folder should contain one link for each session in
the lower "sessions" folders. The name of the link should be the same as
used for the session and the link should point to the session.

Example:

scsi_target
|- sessions
|  |- session-1 -> ../iscsi/iqn.1999-09.com.lio:tgt1/tpgt_2/session-1
|  `- session-2 -> ../iscsi/iqn.1999-09.com.lio:tgt1/tpgt_1/session-2
`- iscsi
    `- iqn.1999-09.com.lio:tgt1
       |- tpgt_1
       |  `- sessions
       |     `- session-2
       `- tpgt_2
          `- sessions
             `- session-1

The link can help to easily find the session for a given session_id and
also provides the wwn/tpg info for a session which together with the
info exposed by the session attributes completes the nexus info.



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [RFC PATCH 08/12] target: add sysfs session helper functions
  2020-04-20 19:14   ` Mike Christie
@ 2020-04-21 16:07     ` Bodo Stroesser
  -1 siblings, 0 replies; 38+ messages in thread
From: Bodo Stroesser @ 2020-04-21 16:07 UTC (permalink / raw)
  To: Mike Christie, jsmart2021, bvanassche, martin.petersen,
	linux-scsi, target-devel

To generate the new, globally unique session ids, idr_alloc_cyclic()
is used. Is there real need for the _cyclic?
Otherwise ida_alloc / ida_free would be sufficient, which saves space,
avoids the se_sess_idr_mutex and shortens the names of the session
folders in sysfs, since low numbers are reused if possible.

On 04/20/20 21:14, Mike Christie wrote:
> This patch adds helpers to add/remove a dir per session. There is
> only 2 files/dirs.
> 
> acl - name of acl session is accessed through.
> transport_id - Contains fabric module specific transportID values.
> 
> iSCSI example:
> 
> scsi_target/
> ├── iscsi
> │   └── iqn.1999-09.com.tcmu:alua
> │       ├── tpgt_1
> │       │   └── sessions
> │       │       └── session-1
> │       │           ├── acl
> │       │           └── transport_id
> │       │               ├── format
> │       │               ├── iscsi_name
> │       │               ├── iscsi_session_id
> │       │               └── proto
> │       └── tpgt_2
> │           └── sessions
> .....
> 
> Fabric drivers like iscsi or elx can add pass in an attribute_group
> to add driver specific attrs via the target_core_fabric_ops
> session_attrs field.
> 
> Note that this adds back the global sid allocator instead of the per tpg
> one because in the future we will want to tag target_core_user commands
> with the session id. This will be needed when tcmu devices are mapped
> to multiple fabric modules or tpgs and they userspace needs to track
> the different session to command mappings for commands like PRs.
> 
> Signed-off-by: Mike Christie <mchristi@redhat.com>
> ---
> V2:
> - Fix extra newline
> - Copy data that's exported to sysfs so we do not have to worry about
> configfs and sysfs refcounts.
> 
>   drivers/target/Makefile                |   1 +
>   drivers/target/target_core_internal.h  |   4 +
>   drivers/target/target_core_sysfs.c     | 296 +++++++++++++++++++++++++++++++++
>   drivers/target/target_core_transport.c |  43 ++++-
>   include/target/target_core_base.h      |   6 +
>   include/target/target_core_fabric.h    |   8 +-
>   6 files changed, 351 insertions(+), 7 deletions(-)
>   create mode 100644 drivers/target/target_core_sysfs.c
> 
> diff --git a/drivers/target/Makefile b/drivers/target/Makefile
> index 4563474..4a7246e 100644
> --- a/drivers/target/Makefile
> +++ b/drivers/target/Makefile
> @@ -1,6 +1,7 @@
>   # SPDX-License-Identifier: GPL-2.0
>   
>   target_core_mod-y		:= target_core_configfs.o \
> +				   target_core_sysfs.o \
>   				   target_core_device.o \
>   				   target_core_fabric_configfs.o \
>   				   target_core_fabric_lib.o \
> diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h
> index d242a97..c85eb30 100644
> --- a/drivers/target/target_core_internal.h
> +++ b/drivers/target/target_core_internal.h
> @@ -108,6 +108,9 @@ const char *target_parse_pr_out_transport_id(struct se_portal_group *tpg,
>   void target_free_transport_id(struct t10_transport_id *tpid);
>   char *transport_id_get_sid(struct t10_transport_id *tpid);
>   
> +/* target_core_sysfs.c */
> +void	target_sysfs_init_session(struct se_session *sess);
> +
>   /* target_core_hba.c */
>   struct se_hba *core_alloc_hba(const char *, u32, u32);
>   int	core_delete_hba(struct se_hba *);
> @@ -155,6 +158,7 @@ void	transport_dump_dev_info(struct se_device *, struct se_lun *,
>   bool	target_check_wce(struct se_device *dev);
>   bool	target_check_fua(struct se_device *dev);
>   void	__target_execute_cmd(struct se_cmd *, bool);
> +void	__target_free_session(struct se_session *);
>   
>   /* target_core_stat.c */
>   void	target_stat_setup_dev_default_groups(struct se_device *);
> diff --git a/drivers/target/target_core_sysfs.c b/drivers/target/target_core_sysfs.c
> new file mode 100644
> index 0000000..d8f2c1e
> --- /dev/null
> +++ b/drivers/target/target_core_sysfs.c
> @@ -0,0 +1,296 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +#include <linux/kobject.h>
> +#include <linux/idr.h>
> +
> +#include <scsi/scsi_proto.h>
> +
> +#include <target/target_core_base.h>
> +#include <target/target_core_fabric.h>
> +#include "target_core_internal.h"
> +
> +static void target_sysfs_session_release(struct kobject *kobj)
> +{
> +	struct se_session *se_sess = container_of(kobj, struct se_session, kobj);
> +
> +	__target_free_session(se_sess);
> +}
> +
> +struct session_attr {
> +	struct attribute attr;
> +	ssize_t (*show)(struct se_session *, char *);
> +	ssize_t (*store)(struct se_session *, const char *, size_t);
> +};
> +
> +#define to_session(atr) container_of((atr), struct session_attr, attr)
> +
> +static ssize_t session_acl_show(struct se_session *se_sess, char *page)
> +{
> +	return snprintf(page, PAGE_SIZE, "%s\n", se_sess->acl_name ?
> +			se_sess->acl_name : "");
> +}
> +
> +static struct session_attr session_acl_attr = {
> +	.attr = { .name = "acl", .mode = S_IRUGO },
> +	.show = session_acl_show,
> +};
> +
> +/* Default attrs common to all fabric modules */
> +static struct attribute *session_attrs[] = {
> +	&session_acl_attr.attr,
> +	NULL
> +};
> +ATTRIBUTE_GROUPS(session);
> +
> +/* transportID attrs */
> +#define transport_id_def_attr_show(name, fmt_str)		\
> +static ssize_t def_show_##name(struct se_session *se_sess, char *page) \
> +{									\
> +	return snprintf(page, PAGE_SIZE, fmt_str, se_sess->tpid->name); \
> +}
> +
> +#define transport_id_def_attr(name, fmt_str)		\
> +	transport_id_def_attr_show(name, fmt_str)		\
> +static struct session_attr transport_id_def_##name##_attr =	\
> +	__ATTR(name, S_IRUGO, def_show_##name, NULL)
> +
> +#define transport_id_attr_show(pref, name, fmt_str)			\
> +static ssize_t show_##pref##_##name(struct se_session *se_sess, char *page) \
> +{									\
> +	return snprintf(page, PAGE_SIZE, fmt_str, se_sess->tpid->pref.name); \
> +}
> +
> +#define transport_id_attr(pref, name, fmt_str)				\
> +	transport_id_attr_show(pref, name, fmt_str)			\
> +static struct session_attr transport_id_##pref##_##name##_attr =	\
> +	__ATTR(name, S_IRUGO, show_##pref##_##name, NULL)
> +
> +transport_id_def_attr(proto, "%u\n");
> +transport_id_def_attr(format, "%u\n");
> +transport_id_attr(fcp, port_name, "%s\n");
> +transport_id_attr(sbp, name, "%s\n");
> +transport_id_attr(srp, port_id, "%s\n");
> +transport_id_attr(sas, addr, "%s\n");
> +transport_id_attr(iscsi, name, "%s\n");
> +transport_id_attr(iscsi, session_id, "%s\n");
> +
> +static struct attribute *transport_id_fcp_attrs[] = {
> +	&transport_id_def_proto_attr.attr,
> +	&transport_id_def_format_attr.attr,
> +	&transport_id_fcp_port_name_attr.attr,
> +	NULL
> +};
> +
> +static struct attribute *transport_id_sbp_attrs[] = {
> +	&transport_id_def_proto_attr.attr,
> +	&transport_id_def_format_attr.attr,
> +	&transport_id_sbp_name_attr.attr,
> +	NULL
> +};
> +
> +static struct attribute *transport_id_srp_attrs[] = {
> +	&transport_id_def_proto_attr.attr,
> +	&transport_id_def_format_attr.attr,
> +	&transport_id_srp_port_id_attr.attr,
> +	NULL
> +};
> +
> +static struct attribute *transport_id_sas_attrs[] = {
> +	&transport_id_def_proto_attr.attr,
> +	&transport_id_def_format_attr.attr,
> +	&transport_id_sas_addr_attr.attr,
> +	NULL
> +};
> +
> +static struct attribute *transport_id_iscsi_attrs[] = {
> +	&transport_id_def_proto_attr.attr,
> +	&transport_id_def_format_attr.attr,
> +	&transport_id_iscsi_name_attr.attr,
> +	&transport_id_iscsi_session_id_attr.attr,
> +	NULL
> +};
> +
> +static const struct attribute_group transport_id_fcp_attr_group = {
> +	.name = "transport_id",
> +	.attrs = transport_id_fcp_attrs,
> +};
> +
> +static const struct attribute_group transport_id_sbp_attr_group = {
> +	.name = "transport_id",
> +	.attrs = transport_id_sbp_attrs,
> +};
> +
> +static const struct attribute_group transport_id_srp_attr_group = {
> +	.name = "transport_id",
> +	.attrs = transport_id_srp_attrs,
> +};
> +
> +static const struct attribute_group transport_id_sas_attr_group = {
> +	.name = "transport_id",
> +	.attrs = transport_id_sas_attrs,
> +};
> +
> +static const struct attribute_group transport_id_iscsi_attr_group = {
> +	.name = "transport_id",
> +	.attrs = transport_id_iscsi_attrs,
> +};
> +
> +static ssize_t
> +session_attr_store(struct kobject *kobj, struct attribute *attr,
> +		   const char *page, size_t length)
> +{
> +	struct se_session *se_sess = container_of(kobj, struct se_session, kobj);
> +	struct session_attr *sess_attr = to_session(attr);
> +
> +	if (!sess_attr->store)
> +		return -ENOSYS;
> +
> +	return sess_attr->store(se_sess, page, length);
> +}
> +
> +static ssize_t
> +session_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
> +{
> +	struct se_session *se_sess = container_of(kobj, struct se_session, kobj);
> +	struct session_attr *sess_attr = to_session(attr);
> +
> +	if (!sess_attr->show)
> +		return -ENOSYS;
> +
> +	return sess_attr->show(se_sess, page);
> +}
> +
> +static const struct sysfs_ops session_sysfs_ops = {
> +	.show	= session_attr_show,
> +	.store	= session_attr_store,
> +};
> +
> +static struct kobj_type session_ktype = {
> +	.sysfs_ops	= &session_sysfs_ops,
> +	.release	= target_sysfs_session_release,
> +	.default_groups	= session_groups,
> +};
> +
> +void target_sysfs_init_session(struct se_session *se_sess)
> +{
> +	kobject_init(&se_sess->kobj, &session_ktype);
> +}
> +
> +static int add_transport_id_attrs(struct se_session *se_sess)
> +{
> +	int ret = 0;
> +
> +	switch (se_sess->tpid->proto) {
> +
> +	case SCSI_PROTOCOL_FCP:
> +		ret = sysfs_create_group(&se_sess->kobj,
> +					 &transport_id_fcp_attr_group);
> +		break;
> +	case SCSI_PROTOCOL_SBP:
> +		ret = sysfs_create_group(&se_sess->kobj,
> +					 &transport_id_sbp_attr_group);
> +		break;
> +	case SCSI_PROTOCOL_SRP:
> +		ret = sysfs_create_group(&se_sess->kobj,
> +					 &transport_id_srp_attr_group);
> +		break;
> +	case SCSI_PROTOCOL_SAS:
> +		ret = sysfs_create_group(&se_sess->kobj,
> +					 &transport_id_sas_attr_group);
> +		break;
> +	case SCSI_PROTOCOL_ISCSI:
> +		ret = sysfs_create_group(&se_sess->kobj,
> +					 &transport_id_iscsi_attr_group);
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
> +static void remove_transport_id_attrs(struct se_session *se_sess)
> +{
> +	switch (se_sess->tpid->proto) {
> +	case SCSI_PROTOCOL_FCP:
> +		sysfs_remove_group(&se_sess->kobj,
> +				   &transport_id_fcp_attr_group);
> +		break;
> +	case SCSI_PROTOCOL_SBP:
> +		sysfs_remove_group(&se_sess->kobj,
> +				   &transport_id_sbp_attr_group);
> +		break;
> +	case SCSI_PROTOCOL_SRP:
> +		sysfs_remove_group(&se_sess->kobj,
> +				   &transport_id_srp_attr_group);
> +		break;
> +	case SCSI_PROTOCOL_SAS:
> +		sysfs_remove_group(&se_sess->kobj,
> +				   &transport_id_sas_attr_group);
> +		break;
> +	case SCSI_PROTOCOL_ISCSI:
> +		sysfs_remove_group(&se_sess->kobj,
> +				   &transport_id_iscsi_attr_group);
> +		break;
> +	}
> +}
> +
> +int target_sysfs_add_session(struct se_portal_group *se_tpg,
> +			     struct se_session *se_sess)
> +{
> +	int ret;
> +
> +	/*
> +	 * Copy ACL name so we don't have to worry about mixing configfs
> +	 * and sysfs refcounts.
> +	 */
> +	if (!se_sess->se_node_acl->dynamic_node_acl) {
> +		se_sess->acl_name = kstrdup(se_sess->se_node_acl->initiatorname,
> +					    GFP_KERNEL);
> +		if (!se_sess->acl_name)
> +			return -ENOMEM;
> +	}
> +
> +	ret = kobject_add(&se_sess->kobj, se_tpg->sessions_kobj, "session-%d",
> +			  se_sess->sid);
> +	if (ret) {
> +		pr_err("Could not add session%d to sysfs. Error %d.\n",
> +		       se_sess->sid, ret);
> +		goto free_acl_name;
> +	}
> +
> +	ret = add_transport_id_attrs(se_sess);
> +	if (ret)
> +		goto del_kobj;
> +
> +	if (se_sess->tfo->session_attrs) {
> +		ret = sysfs_create_group(&se_sess->kobj,
> +					 se_sess->tfo->session_attrs);
> +		if (ret)
> +			goto rm_tpid_grps;
> +	}
> +	se_sess->sysfs_added = true;
> +
> +	return 0;
> +
> +rm_tpid_grps:
> +	remove_transport_id_attrs(se_sess);
> +del_kobj:
> +	kobject_del(&se_sess->kobj);
> +free_acl_name:
> +	kfree(se_sess->acl_name);
> +	se_sess->acl_name = NULL;
> +	return ret;
> +}
> +EXPORT_SYMBOL(target_sysfs_add_session);
> +
> +void target_sysfs_remove_session(struct se_session *se_sess)
> +{
> +	/* discovery sessions are normally not added to sysfs */
> +	if (!se_sess->sysfs_added)
> +		return;
> +
> +	remove_transport_id_attrs(se_sess);
> +
> +	if (se_sess->tfo->session_attrs)
> +		sysfs_remove_group(&se_sess->kobj, se_sess->tfo->session_attrs);
> +	kobject_del(&se_sess->kobj);
> +}
> +EXPORT_SYMBOL(target_sysfs_remove_session);
> diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
> index 66f0af1..d3248d4 100644
> --- a/drivers/target/target_core_transport.c
> +++ b/drivers/target/target_core_transport.c
> @@ -42,6 +42,8 @@
>   
>   static struct workqueue_struct *target_completion_wq;
>   static struct kmem_cache *se_sess_cache;
> +static DEFINE_MUTEX(se_sess_idr_mutex);
> +static DEFINE_IDR(se_sess_idr);
>   struct kmem_cache *se_ua_cache;
>   struct kmem_cache *t10_pr_reg_cache;
>   struct kmem_cache *t10_alua_lu_gp_cache;
> @@ -251,14 +253,32 @@ struct se_session *transport_alloc_session(enum target_prot_op sup_prot_ops)
>   				" se_sess_cache\n");
>   		return ERR_PTR(-ENOMEM);
>   	}
> -	ret = transport_init_session(se_sess);
> +
> +	mutex_lock(&se_sess_idr_mutex);
> +	ret = idr_alloc_cyclic(&se_sess_idr, NULL, 1, 0, GFP_KERNEL);
> +	if (ret >= 0)
> +		se_sess->sid = ret;
> +	mutex_unlock(&se_sess_idr_mutex);
>   	if (ret < 0) {
> -		kmem_cache_free(se_sess_cache, se_sess);
> -		return ERR_PTR(ret);
> +		pr_err("Unable to allocate session index.\n");
> +		goto free_sess;
>   	}
> -	se_sess->sup_prot_ops = sup_prot_ops;
>   
> +	ret = transport_init_session(se_sess);
> +	if (ret < 0)
> +		goto free_sid;
> +
> +	se_sess->sup_prot_ops = sup_prot_ops;
> +	target_sysfs_init_session(se_sess);
>   	return se_sess;
> +
> +free_sid:
> +	mutex_lock(&se_sess_idr_mutex);
> +	idr_remove(&se_sess_idr, se_sess->sid);
> +	mutex_unlock(&se_sess_idr_mutex);
> +free_sess:
> +	kmem_cache_free(se_sess_cache, se_sess);
> +	return ERR_PTR(ret);
>   }
>   EXPORT_SYMBOL(transport_alloc_session);
>   
> @@ -585,12 +605,23 @@ void transport_free_session(struct se_session *se_sess)
>   		sbitmap_queue_free(&se_sess->sess_tag_pool);
>   		kvfree(se_sess->sess_cmd_map);
>   	}
> -	target_free_transport_id(se_sess->tpid);
>   	percpu_ref_exit(&se_sess->cmd_count);
> -	kmem_cache_free(se_sess_cache, se_sess);
> +	kobject_put(&se_sess->kobj);
>   }
>   EXPORT_SYMBOL(transport_free_session);
>   
> +void __target_free_session(struct se_session *se_sess)
> +{
> +	kfree(se_sess->acl_name);
> +	target_free_transport_id(se_sess->tpid);
> +
> +	mutex_lock(&se_sess_idr_mutex);
> +	idr_remove(&se_sess_idr, se_sess->sid);
> +	mutex_unlock(&se_sess_idr_mutex);
> +
> +	kmem_cache_free(se_sess_cache, se_sess);
> +}
> +
>   static int target_release_res(struct se_device *dev, void *data)
>   {
>   	struct se_session *sess = data;
> diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
> index b48f8cf..61115b7 100644
> --- a/include/target/target_core_base.h
> +++ b/include/target/target_core_base.h
> @@ -9,6 +9,7 @@
>   #include <linux/semaphore.h>     /* struct semaphore */
>   #include <linux/completion.h>
>   #include <linux/kobject.h>
> +#include <linux/idr.h>
>   
>   #define TARGET_CORE_VERSION		"v5.0"
>   
> @@ -633,6 +634,7 @@ struct se_session {
>   	enum target_prot_op	sup_prot_ops;
>   	enum target_prot_type	sess_prot_type;
>   	struct se_node_acl	*se_node_acl;
> +	char			*acl_name;
>   	struct se_portal_group *se_tpg;
>   	void			*fabric_sess_ptr;
>   	struct percpu_ref	cmd_count;
> @@ -643,6 +645,10 @@ struct se_session {
>   	wait_queue_head_t	cmd_list_wq;
>   	void			*sess_cmd_map;
>   	struct sbitmap_queue	sess_tag_pool;
> +	struct kobject		kobj;
> +	int			sid;
> +	bool			sysfs_added;
> +	const struct target_core_fabric_ops *tfo;
>   };
>   
>   struct se_device;
> diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
> index 0c1720d..be43180 100644
> --- a/include/target/target_core_fabric.h
> +++ b/include/target/target_core_fabric.h
> @@ -74,6 +74,10 @@ struct target_core_fabric_ops {
>   	int (*queue_status)(struct se_cmd *);
>   	void (*queue_tm_rsp)(struct se_cmd *);
>   	void (*aborted_task)(struct se_cmd *);
> +
> +	/* Optional session management and sysfs callouts */
> +	const struct attribute_group *session_attrs;
> +
>   	/*
>   	 * fabric module calls for target_core_fabric_configfs.c
>   	 */
> @@ -141,7 +145,9 @@ void	transport_register_session(struct se_portal_group *,
>   void	target_put_nacl(struct se_node_acl *);
>   void	transport_deregister_session_configfs(struct se_session *);
>   void	transport_deregister_session(struct se_session *);
> -
> +void	target_sysfs_remove_session(struct se_session *se_sess);
> +int	target_sysfs_add_session(struct se_portal_group *se_tpg,
> +				 struct se_session *se_sess);
>   
>   void	transport_init_se_cmd(struct se_cmd *,
>   		const struct target_core_fabric_ops *,
> 

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [RFC PATCH 08/12] target: add sysfs session helper functions
@ 2020-04-21 16:07     ` Bodo Stroesser
  0 siblings, 0 replies; 38+ messages in thread
From: Bodo Stroesser @ 2020-04-21 16:07 UTC (permalink / raw)
  To: Mike Christie, jsmart2021, bvanassche, martin.petersen,
	linux-scsi, target-devel

To generate the new, globally unique session ids, idr_alloc_cyclic()
is used. Is there real need for the _cyclic?
Otherwise ida_alloc / ida_free would be sufficient, which saves space,
avoids the se_sess_idr_mutex and shortens the names of the session
folders in sysfs, since low numbers are reused if possible.

On 04/20/20 21:14, Mike Christie wrote:
> This patch adds helpers to add/remove a dir per session. There is
> only 2 files/dirs.
> 
> acl - name of acl session is accessed through.
> transport_id - Contains fabric module specific transportID values.
> 
> iSCSI example:
> 
> scsi_target/
> ├── iscsi
> │   └── iqn.1999-09.com.tcmu:alua
> │       ├── tpgt_1
> │       │   └── sessions
> │       │       └── session-1
> │       │           ├── acl
> │       │           └── transport_id
> │       │               ├── format
> │       │               ├── iscsi_name
> │       │               ├── iscsi_session_id
> │       │               └── proto
> │       └── tpgt_2
> │           └── sessions
> .....
> 
> Fabric drivers like iscsi or elx can add pass in an attribute_group
> to add driver specific attrs via the target_core_fabric_ops
> session_attrs field.
> 
> Note that this adds back the global sid allocator instead of the per tpg
> one because in the future we will want to tag target_core_user commands
> with the session id. This will be needed when tcmu devices are mapped
> to multiple fabric modules or tpgs and they userspace needs to track
> the different session to command mappings for commands like PRs.
> 
> Signed-off-by: Mike Christie <mchristi@redhat.com>
> ---
> V2:
> - Fix extra newline
> - Copy data that's exported to sysfs so we do not have to worry about
> configfs and sysfs refcounts.
> 
>   drivers/target/Makefile                |   1 +
>   drivers/target/target_core_internal.h  |   4 +
>   drivers/target/target_core_sysfs.c     | 296 +++++++++++++++++++++++++++++++++
>   drivers/target/target_core_transport.c |  43 ++++-
>   include/target/target_core_base.h      |   6 +
>   include/target/target_core_fabric.h    |   8 +-
>   6 files changed, 351 insertions(+), 7 deletions(-)
>   create mode 100644 drivers/target/target_core_sysfs.c
> 
> diff --git a/drivers/target/Makefile b/drivers/target/Makefile
> index 4563474..4a7246e 100644
> --- a/drivers/target/Makefile
> +++ b/drivers/target/Makefile
> @@ -1,6 +1,7 @@
>   # SPDX-License-Identifier: GPL-2.0
>   
>   target_core_mod-y		:= target_core_configfs.o \
> +				   target_core_sysfs.o \
>   				   target_core_device.o \
>   				   target_core_fabric_configfs.o \
>   				   target_core_fabric_lib.o \
> diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h
> index d242a97..c85eb30 100644
> --- a/drivers/target/target_core_internal.h
> +++ b/drivers/target/target_core_internal.h
> @@ -108,6 +108,9 @@ const char *target_parse_pr_out_transport_id(struct se_portal_group *tpg,
>   void target_free_transport_id(struct t10_transport_id *tpid);
>   char *transport_id_get_sid(struct t10_transport_id *tpid);
>   
> +/* target_core_sysfs.c */
> +void	target_sysfs_init_session(struct se_session *sess);
> +
>   /* target_core_hba.c */
>   struct se_hba *core_alloc_hba(const char *, u32, u32);
>   int	core_delete_hba(struct se_hba *);
> @@ -155,6 +158,7 @@ void	transport_dump_dev_info(struct se_device *, struct se_lun *,
>   bool	target_check_wce(struct se_device *dev);
>   bool	target_check_fua(struct se_device *dev);
>   void	__target_execute_cmd(struct se_cmd *, bool);
> +void	__target_free_session(struct se_session *);
>   
>   /* target_core_stat.c */
>   void	target_stat_setup_dev_default_groups(struct se_device *);
> diff --git a/drivers/target/target_core_sysfs.c b/drivers/target/target_core_sysfs.c
> new file mode 100644
> index 0000000..d8f2c1e
> --- /dev/null
> +++ b/drivers/target/target_core_sysfs.c
> @@ -0,0 +1,296 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +#include <linux/kobject.h>
> +#include <linux/idr.h>
> +
> +#include <scsi/scsi_proto.h>
> +
> +#include <target/target_core_base.h>
> +#include <target/target_core_fabric.h>
> +#include "target_core_internal.h"
> +
> +static void target_sysfs_session_release(struct kobject *kobj)
> +{
> +	struct se_session *se_sess = container_of(kobj, struct se_session, kobj);
> +
> +	__target_free_session(se_sess);
> +}
> +
> +struct session_attr {
> +	struct attribute attr;
> +	ssize_t (*show)(struct se_session *, char *);
> +	ssize_t (*store)(struct se_session *, const char *, size_t);
> +};
> +
> +#define to_session(atr) container_of((atr), struct session_attr, attr)
> +
> +static ssize_t session_acl_show(struct se_session *se_sess, char *page)
> +{
> +	return snprintf(page, PAGE_SIZE, "%s\n", se_sess->acl_name ?
> +			se_sess->acl_name : "");
> +}
> +
> +static struct session_attr session_acl_attr = {
> +	.attr = { .name = "acl", .mode = S_IRUGO },
> +	.show = session_acl_show,
> +};
> +
> +/* Default attrs common to all fabric modules */
> +static struct attribute *session_attrs[] = {
> +	&session_acl_attr.attr,
> +	NULL
> +};
> +ATTRIBUTE_GROUPS(session);
> +
> +/* transportID attrs */
> +#define transport_id_def_attr_show(name, fmt_str)		\
> +static ssize_t def_show_##name(struct se_session *se_sess, char *page) \
> +{									\
> +	return snprintf(page, PAGE_SIZE, fmt_str, se_sess->tpid->name); \
> +}
> +
> +#define transport_id_def_attr(name, fmt_str)		\
> +	transport_id_def_attr_show(name, fmt_str)		\
> +static struct session_attr transport_id_def_##name##_attr =	\
> +	__ATTR(name, S_IRUGO, def_show_##name, NULL)
> +
> +#define transport_id_attr_show(pref, name, fmt_str)			\
> +static ssize_t show_##pref##_##name(struct se_session *se_sess, char *page) \
> +{									\
> +	return snprintf(page, PAGE_SIZE, fmt_str, se_sess->tpid->pref.name); \
> +}
> +
> +#define transport_id_attr(pref, name, fmt_str)				\
> +	transport_id_attr_show(pref, name, fmt_str)			\
> +static struct session_attr transport_id_##pref##_##name##_attr =	\
> +	__ATTR(name, S_IRUGO, show_##pref##_##name, NULL)
> +
> +transport_id_def_attr(proto, "%u\n");
> +transport_id_def_attr(format, "%u\n");
> +transport_id_attr(fcp, port_name, "%s\n");
> +transport_id_attr(sbp, name, "%s\n");
> +transport_id_attr(srp, port_id, "%s\n");
> +transport_id_attr(sas, addr, "%s\n");
> +transport_id_attr(iscsi, name, "%s\n");
> +transport_id_attr(iscsi, session_id, "%s\n");
> +
> +static struct attribute *transport_id_fcp_attrs[] = {
> +	&transport_id_def_proto_attr.attr,
> +	&transport_id_def_format_attr.attr,
> +	&transport_id_fcp_port_name_attr.attr,
> +	NULL
> +};
> +
> +static struct attribute *transport_id_sbp_attrs[] = {
> +	&transport_id_def_proto_attr.attr,
> +	&transport_id_def_format_attr.attr,
> +	&transport_id_sbp_name_attr.attr,
> +	NULL
> +};
> +
> +static struct attribute *transport_id_srp_attrs[] = {
> +	&transport_id_def_proto_attr.attr,
> +	&transport_id_def_format_attr.attr,
> +	&transport_id_srp_port_id_attr.attr,
> +	NULL
> +};
> +
> +static struct attribute *transport_id_sas_attrs[] = {
> +	&transport_id_def_proto_attr.attr,
> +	&transport_id_def_format_attr.attr,
> +	&transport_id_sas_addr_attr.attr,
> +	NULL
> +};
> +
> +static struct attribute *transport_id_iscsi_attrs[] = {
> +	&transport_id_def_proto_attr.attr,
> +	&transport_id_def_format_attr.attr,
> +	&transport_id_iscsi_name_attr.attr,
> +	&transport_id_iscsi_session_id_attr.attr,
> +	NULL
> +};
> +
> +static const struct attribute_group transport_id_fcp_attr_group = {
> +	.name = "transport_id",
> +	.attrs = transport_id_fcp_attrs,
> +};
> +
> +static const struct attribute_group transport_id_sbp_attr_group = {
> +	.name = "transport_id",
> +	.attrs = transport_id_sbp_attrs,
> +};
> +
> +static const struct attribute_group transport_id_srp_attr_group = {
> +	.name = "transport_id",
> +	.attrs = transport_id_srp_attrs,
> +};
> +
> +static const struct attribute_group transport_id_sas_attr_group = {
> +	.name = "transport_id",
> +	.attrs = transport_id_sas_attrs,
> +};
> +
> +static const struct attribute_group transport_id_iscsi_attr_group = {
> +	.name = "transport_id",
> +	.attrs = transport_id_iscsi_attrs,
> +};
> +
> +static ssize_t
> +session_attr_store(struct kobject *kobj, struct attribute *attr,
> +		   const char *page, size_t length)
> +{
> +	struct se_session *se_sess = container_of(kobj, struct se_session, kobj);
> +	struct session_attr *sess_attr = to_session(attr);
> +
> +	if (!sess_attr->store)
> +		return -ENOSYS;
> +
> +	return sess_attr->store(se_sess, page, length);
> +}
> +
> +static ssize_t
> +session_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
> +{
> +	struct se_session *se_sess = container_of(kobj, struct se_session, kobj);
> +	struct session_attr *sess_attr = to_session(attr);
> +
> +	if (!sess_attr->show)
> +		return -ENOSYS;
> +
> +	return sess_attr->show(se_sess, page);
> +}
> +
> +static const struct sysfs_ops session_sysfs_ops = {
> +	.show	= session_attr_show,
> +	.store	= session_attr_store,
> +};
> +
> +static struct kobj_type session_ktype = {
> +	.sysfs_ops	= &session_sysfs_ops,
> +	.release	= target_sysfs_session_release,
> +	.default_groups	= session_groups,
> +};
> +
> +void target_sysfs_init_session(struct se_session *se_sess)
> +{
> +	kobject_init(&se_sess->kobj, &session_ktype);
> +}
> +
> +static int add_transport_id_attrs(struct se_session *se_sess)
> +{
> +	int ret = 0;
> +
> +	switch (se_sess->tpid->proto) {
> +
> +	case SCSI_PROTOCOL_FCP:
> +		ret = sysfs_create_group(&se_sess->kobj,
> +					 &transport_id_fcp_attr_group);
> +		break;
> +	case SCSI_PROTOCOL_SBP:
> +		ret = sysfs_create_group(&se_sess->kobj,
> +					 &transport_id_sbp_attr_group);
> +		break;
> +	case SCSI_PROTOCOL_SRP:
> +		ret = sysfs_create_group(&se_sess->kobj,
> +					 &transport_id_srp_attr_group);
> +		break;
> +	case SCSI_PROTOCOL_SAS:
> +		ret = sysfs_create_group(&se_sess->kobj,
> +					 &transport_id_sas_attr_group);
> +		break;
> +	case SCSI_PROTOCOL_ISCSI:
> +		ret = sysfs_create_group(&se_sess->kobj,
> +					 &transport_id_iscsi_attr_group);
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
> +static void remove_transport_id_attrs(struct se_session *se_sess)
> +{
> +	switch (se_sess->tpid->proto) {
> +	case SCSI_PROTOCOL_FCP:
> +		sysfs_remove_group(&se_sess->kobj,
> +				   &transport_id_fcp_attr_group);
> +		break;
> +	case SCSI_PROTOCOL_SBP:
> +		sysfs_remove_group(&se_sess->kobj,
> +				   &transport_id_sbp_attr_group);
> +		break;
> +	case SCSI_PROTOCOL_SRP:
> +		sysfs_remove_group(&se_sess->kobj,
> +				   &transport_id_srp_attr_group);
> +		break;
> +	case SCSI_PROTOCOL_SAS:
> +		sysfs_remove_group(&se_sess->kobj,
> +				   &transport_id_sas_attr_group);
> +		break;
> +	case SCSI_PROTOCOL_ISCSI:
> +		sysfs_remove_group(&se_sess->kobj,
> +				   &transport_id_iscsi_attr_group);
> +		break;
> +	}
> +}
> +
> +int target_sysfs_add_session(struct se_portal_group *se_tpg,
> +			     struct se_session *se_sess)
> +{
> +	int ret;
> +
> +	/*
> +	 * Copy ACL name so we don't have to worry about mixing configfs
> +	 * and sysfs refcounts.
> +	 */
> +	if (!se_sess->se_node_acl->dynamic_node_acl) {
> +		se_sess->acl_name = kstrdup(se_sess->se_node_acl->initiatorname,
> +					    GFP_KERNEL);
> +		if (!se_sess->acl_name)
> +			return -ENOMEM;
> +	}
> +
> +	ret = kobject_add(&se_sess->kobj, se_tpg->sessions_kobj, "session-%d",
> +			  se_sess->sid);
> +	if (ret) {
> +		pr_err("Could not add session%d to sysfs. Error %d.\n",
> +		       se_sess->sid, ret);
> +		goto free_acl_name;
> +	}
> +
> +	ret = add_transport_id_attrs(se_sess);
> +	if (ret)
> +		goto del_kobj;
> +
> +	if (se_sess->tfo->session_attrs) {
> +		ret = sysfs_create_group(&se_sess->kobj,
> +					 se_sess->tfo->session_attrs);
> +		if (ret)
> +			goto rm_tpid_grps;
> +	}
> +	se_sess->sysfs_added = true;
> +
> +	return 0;
> +
> +rm_tpid_grps:
> +	remove_transport_id_attrs(se_sess);
> +del_kobj:
> +	kobject_del(&se_sess->kobj);
> +free_acl_name:
> +	kfree(se_sess->acl_name);
> +	se_sess->acl_name = NULL;
> +	return ret;
> +}
> +EXPORT_SYMBOL(target_sysfs_add_session);
> +
> +void target_sysfs_remove_session(struct se_session *se_sess)
> +{
> +	/* discovery sessions are normally not added to sysfs */
> +	if (!se_sess->sysfs_added)
> +		return;
> +
> +	remove_transport_id_attrs(se_sess);
> +
> +	if (se_sess->tfo->session_attrs)
> +		sysfs_remove_group(&se_sess->kobj, se_sess->tfo->session_attrs);
> +	kobject_del(&se_sess->kobj);
> +}
> +EXPORT_SYMBOL(target_sysfs_remove_session);
> diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
> index 66f0af1..d3248d4 100644
> --- a/drivers/target/target_core_transport.c
> +++ b/drivers/target/target_core_transport.c
> @@ -42,6 +42,8 @@
>   
>   static struct workqueue_struct *target_completion_wq;
>   static struct kmem_cache *se_sess_cache;
> +static DEFINE_MUTEX(se_sess_idr_mutex);
> +static DEFINE_IDR(se_sess_idr);
>   struct kmem_cache *se_ua_cache;
>   struct kmem_cache *t10_pr_reg_cache;
>   struct kmem_cache *t10_alua_lu_gp_cache;
> @@ -251,14 +253,32 @@ struct se_session *transport_alloc_session(enum target_prot_op sup_prot_ops)
>   				" se_sess_cache\n");
>   		return ERR_PTR(-ENOMEM);
>   	}
> -	ret = transport_init_session(se_sess);
> +
> +	mutex_lock(&se_sess_idr_mutex);
> +	ret = idr_alloc_cyclic(&se_sess_idr, NULL, 1, 0, GFP_KERNEL);
> +	if (ret >= 0)
> +		se_sess->sid = ret;
> +	mutex_unlock(&se_sess_idr_mutex);
>   	if (ret < 0) {
> -		kmem_cache_free(se_sess_cache, se_sess);
> -		return ERR_PTR(ret);
> +		pr_err("Unable to allocate session index.\n");
> +		goto free_sess;
>   	}
> -	se_sess->sup_prot_ops = sup_prot_ops;
>   
> +	ret = transport_init_session(se_sess);
> +	if (ret < 0)
> +		goto free_sid;
> +
> +	se_sess->sup_prot_ops = sup_prot_ops;
> +	target_sysfs_init_session(se_sess);
>   	return se_sess;
> +
> +free_sid:
> +	mutex_lock(&se_sess_idr_mutex);
> +	idr_remove(&se_sess_idr, se_sess->sid);
> +	mutex_unlock(&se_sess_idr_mutex);
> +free_sess:
> +	kmem_cache_free(se_sess_cache, se_sess);
> +	return ERR_PTR(ret);
>   }
>   EXPORT_SYMBOL(transport_alloc_session);
>   
> @@ -585,12 +605,23 @@ void transport_free_session(struct se_session *se_sess)
>   		sbitmap_queue_free(&se_sess->sess_tag_pool);
>   		kvfree(se_sess->sess_cmd_map);
>   	}
> -	target_free_transport_id(se_sess->tpid);
>   	percpu_ref_exit(&se_sess->cmd_count);
> -	kmem_cache_free(se_sess_cache, se_sess);
> +	kobject_put(&se_sess->kobj);
>   }
>   EXPORT_SYMBOL(transport_free_session);
>   
> +void __target_free_session(struct se_session *se_sess)
> +{
> +	kfree(se_sess->acl_name);
> +	target_free_transport_id(se_sess->tpid);
> +
> +	mutex_lock(&se_sess_idr_mutex);
> +	idr_remove(&se_sess_idr, se_sess->sid);
> +	mutex_unlock(&se_sess_idr_mutex);
> +
> +	kmem_cache_free(se_sess_cache, se_sess);
> +}
> +
>   static int target_release_res(struct se_device *dev, void *data)
>   {
>   	struct se_session *sess = data;
> diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
> index b48f8cf..61115b7 100644
> --- a/include/target/target_core_base.h
> +++ b/include/target/target_core_base.h
> @@ -9,6 +9,7 @@
>   #include <linux/semaphore.h>     /* struct semaphore */
>   #include <linux/completion.h>
>   #include <linux/kobject.h>
> +#include <linux/idr.h>
>   
>   #define TARGET_CORE_VERSION		"v5.0"
>   
> @@ -633,6 +634,7 @@ struct se_session {
>   	enum target_prot_op	sup_prot_ops;
>   	enum target_prot_type	sess_prot_type;
>   	struct se_node_acl	*se_node_acl;
> +	char			*acl_name;
>   	struct se_portal_group *se_tpg;
>   	void			*fabric_sess_ptr;
>   	struct percpu_ref	cmd_count;
> @@ -643,6 +645,10 @@ struct se_session {
>   	wait_queue_head_t	cmd_list_wq;
>   	void			*sess_cmd_map;
>   	struct sbitmap_queue	sess_tag_pool;
> +	struct kobject		kobj;
> +	int			sid;
> +	bool			sysfs_added;
> +	const struct target_core_fabric_ops *tfo;
>   };
>   
>   struct se_device;
> diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
> index 0c1720d..be43180 100644
> --- a/include/target/target_core_fabric.h
> +++ b/include/target/target_core_fabric.h
> @@ -74,6 +74,10 @@ struct target_core_fabric_ops {
>   	int (*queue_status)(struct se_cmd *);
>   	void (*queue_tm_rsp)(struct se_cmd *);
>   	void (*aborted_task)(struct se_cmd *);
> +
> +	/* Optional session management and sysfs callouts */
> +	const struct attribute_group *session_attrs;
> +
>   	/*
>   	 * fabric module calls for target_core_fabric_configfs.c
>   	 */
> @@ -141,7 +145,9 @@ void	transport_register_session(struct se_portal_group *,
>   void	target_put_nacl(struct se_node_acl *);
>   void	transport_deregister_session_configfs(struct se_session *);
>   void	transport_deregister_session(struct se_session *);
> -
> +void	target_sysfs_remove_session(struct se_session *se_sess);
> +int	target_sysfs_add_session(struct se_portal_group *se_tpg,
> +				 struct se_session *se_sess);
>   
>   void	transport_init_se_cmd(struct se_cmd *,
>   		const struct target_core_fabric_ops *,
> 

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [RFC PATCH 11/12] iscsi target: use session sysfs helpers
  2020-04-20 19:14   ` Mike Christie
@ 2020-04-21 16:26     ` Bodo Stroesser
  -1 siblings, 0 replies; 38+ messages in thread
From: Bodo Stroesser @ 2020-04-21 16:26 UTC (permalink / raw)
  To: Mike Christie, jsmart2021, bvanassche, martin.petersen,
	linux-scsi, target-devel

On 04/20/20 21:14, Mike Christie wrote:

...

> diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
> index f533308..a0ea60f 100644
> --- a/drivers/target/iscsi/iscsi_target_login.c
> +++ b/drivers/target/iscsi/iscsi_target_login.c

...

> @@ -313,7 +303,7 @@ static int iscsi_login_zero_tsih_s1(
>   				ISCSI_LOGIN_STATUS_NO_RESOURCES);
>   		pr_err("Unable to allocate memory for"
>   				" struct iscsi_sess_ops.\n");
> -		goto free_id;
> +		goto free_ops;

Shouldn' this be "goto free_sess;"?

>   	}
>   
>   	sess->se_sess = transport_alloc_session(TARGET_PROT_NORMAL);
> @@ -327,8 +317,6 @@ static int iscsi_login_zero_tsih_s1(
>   
>   free_ops:
>   	kfree(sess->sess_ops);
> -free_id:
> -	ida_free(&sess_ida, sess->session_index);
>   free_sess:
>   	kfree(sess);
>   	conn->sess = NULL;

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [RFC PATCH 11/12] iscsi target: use session sysfs helpers
@ 2020-04-21 16:26     ` Bodo Stroesser
  0 siblings, 0 replies; 38+ messages in thread
From: Bodo Stroesser @ 2020-04-21 16:26 UTC (permalink / raw)
  To: Mike Christie, jsmart2021, bvanassche, martin.petersen,
	linux-scsi, target-devel

On 04/20/20 21:14, Mike Christie wrote:

...

> diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
> index f533308..a0ea60f 100644
> --- a/drivers/target/iscsi/iscsi_target_login.c
> +++ b/drivers/target/iscsi/iscsi_target_login.c

...

> @@ -313,7 +303,7 @@ static int iscsi_login_zero_tsih_s1(
>   				ISCSI_LOGIN_STATUS_NO_RESOURCES);
>   		pr_err("Unable to allocate memory for"
>   				" struct iscsi_sess_ops.\n");
> -		goto free_id;
> +		goto free_ops;

Shouldn' this be "goto free_sess;"?

>   	}
>   
>   	sess->se_sess = transport_alloc_session(TARGET_PROT_NORMAL);
> @@ -327,8 +317,6 @@ static int iscsi_login_zero_tsih_s1(
>   
>   free_ops:
>   	kfree(sess->sess_ops);
> -free_id:
> -	ida_free(&sess_ida, sess->session_index);
>   free_sess:
>   	kfree(sess);
>   	conn->sess = NULL;

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [RFC PATCH 02/12] target: separate acl name from port ids
  2020-04-21 14:49     ` Bodo Stroesser
@ 2020-04-21 17:09       ` Mike Christie
  -1 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-21 17:09 UTC (permalink / raw)
  To: Bodo Stroesser, jsmart2021, bvanassche, martin.petersen,
	linux-scsi, target-devel

On 04/21/2020 09:49 AM, Bodo Stroesser wrote:
> I'm wondering, whether the 'format' element of the new t10_transport_id
> structure is useful:
> 
> - It is used for iSCSI only, but is a common field for all protocols.
> 
> - In iSCSI, if format is 0 then session_id is NULL, and if format is
>   not 0 then session_id is not NULL. So session_id can be used for the
>   same purpose.
> 
> - I think it is a bug that tcm_loop and vhost claim to run iSCSI
>   protocol, but don't deliver an ISID. They e.g. could use the "Random"
>   format for the ISID, which starts with byte 0x80 followed by 3 random
>   bytes and 2 further bytes denoting the session.
> 
> Removing the format element would of course mean to not add the "format"
> session attribute later. (The "session_id" attribute doesn't even check
> format, but uses session_id as argument to "%s" in snprintf even if it
> is NULL).

Yeah, I was just letting it print "NULL" like the other stat file we
have that prints out the isid.

I can just drop format and it will print out "" like the ACL file.

> 
> 
> On 04/20/20 21:14, Mike Christie wrote:
>> To handle features like PGRs in userspace we need the entire iniaitor
>> port id. For iscsi that is defined as the initiator name plus the
>> session identifier. The session id is hidden from users, because
>> its internal to the drivers, so this patch separates the acl name
>> from the SCSI port ids.
>>
>> This will then allow other drivers like SRP to use different values
>> like the port id or src address for the ACL, but then use the port
>> id for transport ID checks in target_core_fabric.c.
>>
>> This will also be used to export the initiator info in the session's
>> sysfs dir in the last patches, so tools like tcmu-runner can rebuild
>> its session state used when handling PGR commands.
>>
>> Signed-off-by: Mike Christie <mchristi@redhat.com>
>> ---
>>   drivers/infiniband/ulp/srpt/ib_srpt.c    | 13 +++--
>>   drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c |  9 +++-
>>   drivers/scsi/qla2xxx/tcm_qla2xxx.c       |  8 ++-
>>   drivers/target/loopback/tcm_loop.c       | 24 ++++++++-
>>   drivers/target/sbp/sbp_target.c          |  9 +++-
>>   drivers/target/target_core_fabric_lib.c  | 87
>> ++++++++++++++++++++++++++++++++
>>   drivers/target/target_core_internal.h    |  1 +
>>   drivers/target/target_core_transport.c   | 22 +++++---
>>   drivers/target/tcm_fc/tfc_sess.c         | 10 +++-
>>   drivers/usb/gadget/function/f_tcm.c      | 11 +++-
>>   drivers/vhost/scsi.c                     | 25 +++++++--
>>   drivers/xen/xen-scsiback.c               | 28 ++++++++--
>>   include/target/target_core_base.h        | 24 +++++++++
>>   include/target/target_core_fabric.h      |  3 +-
>>   14 files changed, 245 insertions(+), 29 deletions(-)
>>
>> diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c
>> b/drivers/infiniband/ulp/srpt/ib_srpt.c
>> index 9855274..caeb32e 100644
>> --- a/drivers/infiniband/ulp/srpt/ib_srpt.c
>> +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
>> @@ -2144,6 +2144,7 @@ static int srpt_cm_req_recv(struct srpt_device
>> *const sdev,
>>                   const char *src_addr)
>>   {
>>       struct srpt_port *sport = &sdev->port[port_num - 1];
>> +    struct t10_transport_id tpid;
>>       struct srpt_nexus *nexus;
>>       struct srp_login_rsp *rsp = NULL;
>>       struct srp_login_rej *rej = NULL;
>> @@ -2314,13 +2315,17 @@ static int srpt_cm_req_recv(struct srpt_device
>> *const sdev,
>>       tag_num = ch->rq_size;
>>       tag_size = 1; /* ib_srpt does not use se_sess->sess_cmd_map */
>>   +    memset(&tpid, 0, sizeof(tpid));
>> +    tpid.proto = SCSI_PROTOCOL_SRP;
>> +    tpid.srp.port_id = i_port_id + 2;
>> +
>>       mutex_lock(&sport->port_guid_id.mutex);
>>       list_for_each_entry(stpg, &sport->port_guid_id.tpg_list, entry) {
>>           if (!IS_ERR_OR_NULL(ch->sess))
>>               break;
>>           ch->sess = target_setup_session(&stpg->tpg, tag_num,
>>                           tag_size, TARGET_PROT_NORMAL,
>> -                        ch->sess_name, ch, NULL);
>> +                        &tpid, ch->sess_name, ch, NULL);
>>       }
>>       mutex_unlock(&sport->port_guid_id.mutex);
>>   @@ -2329,14 +2334,14 @@ static int srpt_cm_req_recv(struct
>> srpt_device *const sdev,
>>           if (!IS_ERR_OR_NULL(ch->sess))
>>               break;
>>           ch->sess = target_setup_session(&stpg->tpg, tag_num,
>> -                    tag_size, TARGET_PROT_NORMAL, i_port_id,
>> -                    ch, NULL);
>> +                    tag_size, TARGET_PROT_NORMAL, &tpid,
>> +                    i_port_id, ch, NULL);
>>           if (!IS_ERR_OR_NULL(ch->sess))
>>               break;
>>           /* Retry without leading "0x" */
>>           ch->sess = target_setup_session(&stpg->tpg, tag_num,
>>                           tag_size, TARGET_PROT_NORMAL,
>> -                        i_port_id + 2, ch, NULL);
>> +                        &tpid, i_port_id + 2, ch, NULL);
>>       }
>>       mutex_unlock(&sport->port_gid_id.mutex);
>>   diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
>> b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
>> index d9e94e8..dba9ec0 100644
>> --- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
>> +++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
>> @@ -2208,6 +2208,7 @@ static int ibmvscsis_make_nexus(struct
>> ibmvscsis_tport *tport)
>>   {
>>       char *name = tport->tport_name;
>>       struct ibmvscsis_nexus *nexus;
>> +    struct t10_transport_id tpid;
>>       struct scsi_info *vscsi = container_of(tport, struct scsi_info,
>> tport);
>>       int rc;
>>   @@ -2222,9 +2223,13 @@ static int ibmvscsis_make_nexus(struct
>> ibmvscsis_tport *tport)
>>           return -ENOMEM;
>>       }
>>   +    memset(&tpid, 0, sizeof(tpid));
>> +    tpid.proto = SCSI_PROTOCOL_SRP;
>> +    tpid.srp.port_id = name;
>> +
>>       nexus->se_sess = target_setup_session(&tport->se_tpg, 0, 0,
>> -                          TARGET_PROT_NORMAL, name, nexus,
>> -                          NULL);
>> +                          TARGET_PROT_NORMAL, &tpid, name,
>> +                          nexus, NULL);
>>       if (IS_ERR(nexus->se_sess)) {
>>           rc = PTR_ERR(nexus->se_sess);
>>           goto transport_init_fail;
>> diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
>> b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
>> index abe7f79..42a4025 100644
>> --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
>> +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
>> @@ -1428,6 +1428,7 @@ static int tcm_qla2xxx_check_initiator_node_acl(
>>   {
>>       struct qla_hw_data *ha = vha->hw;
>>       struct tcm_qla2xxx_lport *lport;
>> +    struct t10_transport_id tpid;
>>       struct tcm_qla2xxx_tpg *tpg;
>>       struct se_session *se_sess;
>>       unsigned char port_name[36];
>> @@ -1454,13 +1455,18 @@ static int tcm_qla2xxx_check_initiator_node_acl(
>>        */
>>       memset(&port_name, 0, 36);
>>       snprintf(port_name, sizeof(port_name), "%8phC", fc_wwpn);
>> +
>> +    memset(&tpid, 0, sizeof(tpid));
>> +    tpid.proto = SCSI_PROTOCOL_FCP;
>> +    tpid.fcp.port_name = port_name;
>> +
>>       /*
>>        * Locate our struct se_node_acl either from an explict NodeACL
>> created
>>        * via ConfigFS, or via running in TPG demo mode.
>>        */
>>       se_sess = target_setup_session(&tpg->se_tpg, num_tags,
>>                          sizeof(struct qla_tgt_cmd),
>> -                       TARGET_PROT_ALL, port_name,
>> +                       TARGET_PROT_ALL, &tpid, port_name,
>>                          qlat_sess, tcm_qla2xxx_session_cb);
>>       if (IS_ERR(se_sess))
>>           return PTR_ERR(se_sess);
>> diff --git a/drivers/target/loopback/tcm_loop.c
>> b/drivers/target/loopback/tcm_loop.c
>> index 3305b47..7593a53 100644
>> --- a/drivers/target/loopback/tcm_loop.c
>> +++ b/drivers/target/loopback/tcm_loop.c
>> @@ -725,10 +725,11 @@ static int tcm_loop_alloc_sess_cb(struct
>> se_portal_group *se_tpg,
>>     static int tcm_loop_make_nexus(
>>       struct tcm_loop_tpg *tl_tpg,
>> -    const char *name)
>> +    char *name)
>>   {
>>       struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
>>       struct tcm_loop_nexus *tl_nexus;
>> +    struct t10_transport_id tpid;
>>       int ret;
>>         if (tl_tpg->tl_nexus) {
>> @@ -736,13 +737,32 @@ static int tcm_loop_make_nexus(
>>           return -EEXIST;
>>       }
>>   +    memset(&tpid, 0, sizeof(tpid));
>> +    tpid.proto = tl_hba->tl_proto_id;
>> +
>> +    switch (tpid.proto) {
>> +    case SCSI_PROTOCOL_SAS:
>> +        tpid.sas.addr = name;
>> +        break;
>> +    case SCSI_PROTOCOL_FCP:
>> +        tpid.fcp.port_name = name;
>> +        break;
>> +    case SCSI_PROTOCOL_ISCSI:
>> +        /* we only support format=0 */
>> +        tpid.iscsi.name = name;
>> +        break;
>> +    default:
>> +        return -EINVAL;
>> +    }
>> +
>>       tl_nexus = kzalloc(sizeof(*tl_nexus), GFP_KERNEL);
>>       if (!tl_nexus)
>>           return -ENOMEM;
>>         tl_nexus->se_sess = target_setup_session(&tl_tpg->tl_se_tpg,
>> 0, 0,
>>                       TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS,
>> -                    name, tl_nexus, tcm_loop_alloc_sess_cb);
>> +                    &tpid, name, tl_nexus,
>> +                    tcm_loop_alloc_sess_cb);
>>       if (IS_ERR(tl_nexus->se_sess)) {
>>           ret = PTR_ERR(tl_nexus->se_sess);
>>           kfree(tl_nexus);
>> diff --git a/drivers/target/sbp/sbp_target.c
>> b/drivers/target/sbp/sbp_target.c
>> index e4a9b9f..9a3121d 100644
>> --- a/drivers/target/sbp/sbp_target.c
>> +++ b/drivers/target/sbp/sbp_target.c
>> @@ -181,6 +181,7 @@ static struct sbp_session *sbp_session_create(
>>           struct sbp_tpg *tpg,
>>           u64 guid)
>>   {
>> +    struct t10_transport_id tpid;
>>       struct sbp_session *sess;
>>       int ret;
>>       char guid_str[17];
>> @@ -196,10 +197,14 @@ static struct sbp_session *sbp_session_create(
>>       INIT_DELAYED_WORK(&sess->maint_work, session_maintenance_work);
>>       sess->guid = guid;
>>   +    memset(&tpid, 0, sizeof(tpid));
>> +    tpid.proto = SCSI_PROTOCOL_SBP;
>> +    tpid.sbp.name = guid_str;
>> +
>>       sess->se_sess = target_setup_session(&tpg->se_tpg, 128,
>>                            sizeof(struct sbp_target_request),
>> -                         TARGET_PROT_NORMAL, guid_str,
>> -                         sess, NULL);
>> +                         TARGET_PROT_NORMAL, &tpid,
>> +                         guid_str, sess, NULL);
>>       if (IS_ERR(sess->se_sess)) {
>>           pr_err("failed to init se_session\n");
>>           ret = PTR_ERR(sess->se_sess);
>> diff --git a/drivers/target/target_core_fabric_lib.c
>> b/drivers/target/target_core_fabric_lib.c
>> index 6b4b354..39b0e5e 100644
>> --- a/drivers/target/target_core_fabric_lib.c
>> +++ b/drivers/target/target_core_fabric_lib.c
>> @@ -421,3 +421,90 @@ const char
>> *target_parse_pr_out_transport_id(struct se_portal_group *tpg,
>>       *out_tid_len = 24;
>>       return buf + offset;
>>   }
>> +
>> +struct t10_transport_id *target_cp_transport_id(struct
>> t10_transport_id *src)
>> +{
>> +    struct t10_transport_id *dst;
>> +
>> +    dst = kzalloc(sizeof(*dst), GFP_KERNEL);
>> +    if (!dst)
>> +        return NULL;
>> +    dst->format = src->format;
>> +    dst->proto = src->proto;
>> +
>> +    switch (src->proto) {
>> +    case SCSI_PROTOCOL_FCP:
>> +        dst->fcp.port_name = kstrdup(src->fcp.port_name, GFP_KERNEL);
>> +        if (!dst->fcp.port_name)
>> +            goto free_tpid;
>> +        break;
>> +    case SCSI_PROTOCOL_SBP:
>> +        dst->sbp.name = kstrdup(src->sbp.name, GFP_KERNEL);
>> +        if (!dst->sbp.name)
>> +            goto free_tpid;
>> +        break;
>> +    case SCSI_PROTOCOL_SRP:
>> +        dst->srp.port_id = kstrdup(src->srp.port_id, GFP_KERNEL);
>> +        if (!dst->srp.port_id)
>> +            goto free_tpid;
>> +        break;
>> +    case SCSI_PROTOCOL_SAS:
>> +        dst->sas.addr = kstrdup(src->sas.addr, GFP_KERNEL);
>> +        if (!dst->sas.addr)
>> +            goto free_tpid;
>> +        break;
>> +    case SCSI_PROTOCOL_ISCSI:
>> +        dst->iscsi.name = kstrdup(src->iscsi.name, GFP_KERNEL);
>> +        if (!dst->iscsi.name)
>> +            goto free_tpid;
>> +
>> +        if (src->format) {
>> +            dst->iscsi.session_id = kstrdup(src->iscsi.session_id,
>> +                            GFP_KERNEL);
>> +            if (!dst->iscsi.session_id) {
>> +                kfree(dst->iscsi.name);
>> +                goto free_tpid;
>> +            }
>> +        }
>> +        break;
>> +    default:
>> +        pr_err("Unknown proto_id: 0x%02x\n", src->proto);
>> +        return NULL;
>> +    }
>> +
>> +    return dst;
>> +
>> +free_tpid:
>> +    kfree(dst);
>> +    return NULL;
>> +}
>> +EXPORT_SYMBOL(target_cp_transport_id);
>> +
>> +void target_free_transport_id(struct t10_transport_id *tpid)
>> +{
>> +    if (!tpid)
>> +        return;
>> +
>> +    switch (tpid->proto) {
>> +    case SCSI_PROTOCOL_FCP:
>> +        kfree(tpid->fcp.port_name);
>> +        break;
>> +    case SCSI_PROTOCOL_SBP:
>> +        kfree(tpid->sbp.name);
>> +        break;
>> +    case SCSI_PROTOCOL_SRP:
>> +        kfree(tpid->srp.port_id);
>> +        break;
>> +    case SCSI_PROTOCOL_SAS:
>> +        kfree(tpid->sas.addr);
>> +        break;
>> +    case SCSI_PROTOCOL_ISCSI:
>> +        kfree(tpid->iscsi.name);
>> +        kfree(tpid->iscsi.session_id);
>> +        break;
>> +    default:
>> +        pr_err("Unknown proto_id: 0x%02x\n", tpid->proto);
>> +        return;
>> +    }
>> +    kfree(tpid);
>> +}
>> diff --git a/drivers/target/target_core_internal.h
>> b/drivers/target/target_core_internal.h
>> index 8533444..5e016aa 100644
>> --- a/drivers/target/target_core_internal.h
>> +++ b/drivers/target/target_core_internal.h
>> @@ -104,6 +104,7 @@ int    target_get_pr_transport_id(struct
>> se_node_acl *nacl,
>>           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);
>> +void target_free_transport_id(struct t10_transport_id *tpid);
>>     /* target_core_hba.c */
>>   struct se_hba *core_alloc_hba(const char *, u32, u32);
>> diff --git a/drivers/target/target_core_transport.c
>> b/drivers/target/target_core_transport.c
>> index 0ae9e60..adf4a84 100644
>> --- a/drivers/target/target_core_transport.c
>> +++ b/drivers/target/target_core_transport.c
>> @@ -416,12 +416,13 @@ void transport_register_session(
>>   struct se_session *
>>   target_setup_session(struct se_portal_group *tpg,
>>                unsigned int tag_num, unsigned int tag_size,
>> -             enum target_prot_op prot_op,
>> +             enum target_prot_op prot_op, struct t10_transport_id *tpid,
>>                const char *initiatorname, void *private,
>>                int (*callback)(struct se_portal_group *,
>>                        struct se_session *, void *))
>>   {
>>       struct se_session *sess;
>> +    int rc;
>>         /*
>>        * If the fabric driver is using percpu-ida based pre allocation
>> @@ -435,6 +436,12 @@ struct se_session *
>>       if (IS_ERR(sess))
>>           return sess;
>>   +    sess->tpid = target_cp_transport_id(tpid);
>> +    if (!sess->tpid) {
>> +        rc = -ENOMEM;
>> +        goto free_sess;
>> +    }
>> +
>>       sess->se_node_acl = core_tpg_check_initiator_node_acl(tpg,
>>                       (unsigned char *)initiatorname);
>>       if (!sess->se_node_acl) {
>> @@ -446,15 +453,17 @@ struct se_session *
>>        * required before transport_register_session().
>>        */
>>       if (callback != NULL) {
>> -        int rc = callback(tpg, sess, private);
>> -        if (rc) {
>> -            transport_free_session(sess);
>> -            return ERR_PTR(rc);
>> -        }
>> +        rc = callback(tpg, sess, private);
>> +        if (rc)
>> +            goto free_sess;
>>       }
>>         transport_register_session(tpg, sess->se_node_acl, sess,
>> private);
>>       return sess;
>> +
>> +free_sess:
>> +    transport_free_session(sess);
>> +    return ERR_PTR(rc);
>>   }
>>   EXPORT_SYMBOL(target_setup_session);
>>   @@ -579,6 +588,7 @@ void transport_free_session(struct se_session
>> *se_sess)
>>           sbitmap_queue_free(&se_sess->sess_tag_pool);
>>           kvfree(se_sess->sess_cmd_map);
>>       }
>> +    target_free_transport_id(se_sess->tpid);
>>       percpu_ref_exit(&se_sess->cmd_count);
>>       kmem_cache_free(se_sess_cache, se_sess);
>>   }
>> diff --git a/drivers/target/tcm_fc/tfc_sess.c
>> b/drivers/target/tcm_fc/tfc_sess.c
>> index 4fd6a1d..f261756 100644
>> --- a/drivers/target/tcm_fc/tfc_sess.c
>> +++ b/drivers/target/tcm_fc/tfc_sess.c
>> @@ -208,6 +208,7 @@ static struct ft_sess *ft_sess_create(struct
>> ft_tport *tport, u32 port_id,
>>                         struct fc_rport_priv *rdata)
>>   {
>>       struct se_portal_group *se_tpg = &tport->tpg->se_tpg;
>> +    struct t10_transport_id tpid;
>>       struct ft_sess *sess;
>>       struct hlist_head *head;
>>       unsigned char initiatorname[TRANSPORT_IQN_LEN];
>> @@ -227,10 +228,15 @@ static struct ft_sess *ft_sess_create(struct
>> ft_tport *tport, u32 port_id,
>>       sess->tport = tport;
>>       sess->port_id = port_id;
>>   +    memset(&tpid, 0, sizeof(tpid));
>> +    tpid.proto = SCSI_PROTOCOL_FCP;
>> +    tpid.fcp.port_name = &initiatorname[0];
>> +
>>       sess->se_sess = target_setup_session(se_tpg, TCM_FC_DEFAULT_TAGS,
>>                            sizeof(struct ft_cmd),
>> -                         TARGET_PROT_NORMAL, &initiatorname[0],
>> -                         sess, ft_sess_alloc_cb);
>> +                         TARGET_PROT_NORMAL, &tpid,
>> +                         &initiatorname[0], sess,
>> +                         ft_sess_alloc_cb);
>>       if (IS_ERR(sess->se_sess)) {
>>           int rc = PTR_ERR(sess->se_sess);
>>           kfree(sess);
>> diff --git a/drivers/usb/gadget/function/f_tcm.c
>> b/drivers/usb/gadget/function/f_tcm.c
>> index 3650493..e282eb9 100644
>> --- a/drivers/usb/gadget/function/f_tcm.c
>> +++ b/drivers/usb/gadget/function/f_tcm.c
>> @@ -1564,6 +1564,7 @@ static int usbg_alloc_sess_cb(struct
>> se_portal_group *se_tpg,
>>   static int tcm_usbg_make_nexus(struct usbg_tpg *tpg, char *name)
>>   {
>>       struct tcm_usbg_nexus *tv_nexus;
>> +    struct t10_transport_id tpid;
>>       int ret = 0;
>>         mutex_lock(&tpg->tpg_mutex);
>> @@ -1579,11 +1580,17 @@ static int tcm_usbg_make_nexus(struct usbg_tpg
>> *tpg, char *name)
>>           goto out_unlock;
>>       }
>>   +    memset(&tpid, 0, sizeof(tpid));
>> +    tpid.proto = tpg->se_tpg.proto_id;
>> +    /* SPC does not assign a proto id for USB-SCSI so we use SAS
>> naming */
>> +    tpid.sas.addr = name;
>> +
>>       tv_nexus->tvn_se_sess = target_setup_session(&tpg->se_tpg,
>>                                USB_G_DEFAULT_SESSION_TAGS,
>>                                sizeof(struct usbg_cmd),
>> -                             TARGET_PROT_NORMAL, name,
>> -                             tv_nexus, usbg_alloc_sess_cb);
>> +                             TARGET_PROT_NORMAL, &tpid,
>> +                             name, tv_nexus,
>> +                             usbg_alloc_sess_cb);
>>       if (IS_ERR(tv_nexus->tvn_se_sess)) {
>>   #define MAKE_NEXUS_MSG "core_tpg_check_initiator_node_acl() failed
>> for %s\n"
>>           pr_debug(MAKE_NEXUS_MSG, name);
>> diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
>> index 0b949a1..bc377ee 100644
>> --- a/drivers/vhost/scsi.c
>> +++ b/drivers/vhost/scsi.c
>> @@ -1937,10 +1937,10 @@ static int vhost_scsi_nexus_cb(struct
>> se_portal_group *se_tpg,
>>       return -ENOMEM;
>>   }
>>   -static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg,
>> -                const char *name)
>> +static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg, char *name)
>>   {
>>       struct vhost_scsi_nexus *tv_nexus;
>> +    struct t10_transport_id tpid;
>>         mutex_lock(&tpg->tv_tpg_mutex);
>>       if (tpg->tpg_nexus) {
>> @@ -1949,6 +1949,25 @@ static int vhost_scsi_make_nexus(struct
>> vhost_scsi_tpg *tpg,
>>           return -EEXIST;
>>       }
>>   +    memset(&tpid, 0, sizeof(tpid));
>> +    tpid.proto = tpg->se_tpg.proto_id;
>> +
>> +    switch (tpid.proto) {
>> +    case SCSI_PROTOCOL_SAS:
>> +        tpid.sas.addr = name;
>> +        break;
>> +    case SCSI_PROTOCOL_FCP:
>> +        tpid.fcp.port_name = name;
>> +        break;
>> +    case SCSI_PROTOCOL_ISCSI:
>> +        /* we only support format=0 */
>> +        tpid.iscsi.name = name;
>> +        break;
>> +    default:
>> +        mutex_unlock(&tpg->tv_tpg_mutex);
>> +        return -EINVAL;
>> +    }
>> +
>>       tv_nexus = kzalloc(sizeof(*tv_nexus), GFP_KERNEL);
>>       if (!tv_nexus) {
>>           mutex_unlock(&tpg->tv_tpg_mutex);
>> @@ -1964,7 +1983,7 @@ static int vhost_scsi_make_nexus(struct
>> vhost_scsi_tpg *tpg,
>>                       VHOST_SCSI_DEFAULT_TAGS,
>>                       sizeof(struct vhost_scsi_cmd),
>>                       TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS,
>> -                    (unsigned char *)name, tv_nexus,
>> +                    &tpid, (unsigned char *)name, tv_nexus,
>>                       vhost_scsi_nexus_cb);
>>       if (IS_ERR(tv_nexus->tvn_se_sess)) {
>>           mutex_unlock(&tpg->tv_tpg_mutex);
>> diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
>> index ba0942e..0855a77f 100644
>> --- a/drivers/xen/xen-scsiback.c
>> +++ b/drivers/xen/xen-scsiback.c
>> @@ -1507,10 +1507,10 @@ static int scsiback_alloc_sess_cb(struct
>> se_portal_group *se_tpg,
>>       return 0;
>>   }
>>   -static int scsiback_make_nexus(struct scsiback_tpg *tpg,
>> -                const char *name)
>> +static int scsiback_make_nexus(struct scsiback_tpg *tpg, char *name)
>>   {
>>       struct scsiback_nexus *tv_nexus;
>> +    struct t10_transport_id tpid;
>>       int ret = 0;
>>         mutex_lock(&tpg->tv_tpg_mutex);
>> @@ -1520,6 +1520,25 @@ static int scsiback_make_nexus(struct
>> scsiback_tpg *tpg,
>>           goto out_unlock;
>>       }
>>   +    memset(&tpid, 0, sizeof(tpid));
>> +    tpid.proto = tpg->se_tpg.proto_id;
>> +
>> +    switch (tpid.proto) {
>> +    case SCSI_PROTOCOL_SAS:
>> +        tpid.sas.addr = name;
>> +        break;
>> +    case SCSI_PROTOCOL_FCP:
>> +        tpid.fcp.port_name = name;
>> +        break;
>> +    case SCSI_PROTOCOL_ISCSI:
>> +        /* we only support format=0 */
>> +        tpid.iscsi.name = name;
>> +        break;
>> +    default:
>> +        ret =-EINVAL;
>> +        goto out_unlock;
>> +    }
>> +
>>       tv_nexus = kzalloc(sizeof(struct scsiback_nexus), GFP_KERNEL);
>>       if (!tv_nexus) {
>>           ret = -ENOMEM;
>> @@ -1529,8 +1548,9 @@ static int scsiback_make_nexus(struct
>> scsiback_tpg *tpg,
>>       tv_nexus->tvn_se_sess = target_setup_session(&tpg->se_tpg,
>>                                VSCSI_DEFAULT_SESSION_TAGS,
>>                                sizeof(struct vscsibk_pend),
>> -                             TARGET_PROT_NORMAL, name,
>> -                             tv_nexus, scsiback_alloc_sess_cb);
>> +                             TARGET_PROT_NORMAL, &tpid,
>> +                             name, tv_nexus,
>> +                             scsiback_alloc_sess_cb);
>>       if (IS_ERR(tv_nexus->tvn_se_sess)) {
>>           kfree(tv_nexus);
>>           ret = -ENOMEM;
>> diff --git a/include/target/target_core_base.h
>> b/include/target/target_core_base.h
>> index 1728e88..cd440ea 100644
>> --- a/include/target/target_core_base.h
>> +++ b/include/target/target_core_base.h
>> @@ -333,6 +333,29 @@ struct t10_wwn {
>>       struct list_head t10_vpd_list;
>>   };
>>   +struct t10_transport_id {
>> +    union {
>> +        struct {
>> +            char *port_name;
>> +        } fcp;
>> +        struct {
>> +            char *addr;
>> +        } sas;
>> +        struct {
>> +            char *name;
>> +        } sbp;
>> +        struct {
>> +            char *port_id;
>> +        } srp;
>> +        struct {
>> +            char *name;
>> +            char *session_id;
>> +        } iscsi;
>> +    };
>> +    u8 format;
>> +    u8 proto;
>> +};
>> +
>>   struct t10_pr_registration {
>>       /* Used for fabrics that contain WWN+ISID */
>>   #define PR_REG_ISID_LEN                16
>> @@ -605,6 +628,7 @@ static inline struct se_node_acl
>> *fabric_stat_to_nacl(struct config_item *item)
>>   struct se_session {
>>       unsigned        sess_tearing_down:1;
>>       u64            sess_bin_isid;
>> +    struct t10_transport_id    *tpid;
>>       enum target_prot_op    sup_prot_ops;
>>       enum target_prot_type    sess_prot_type;
>>       struct se_node_acl    *se_node_acl;
>> diff --git a/include/target/target_core_fabric.h
>> b/include/target/target_core_fabric.h
>> index 063f133..6b8a6bc 100644
>> --- a/include/target/target_core_fabric.h
>> +++ b/include/target/target_core_fabric.h
>> @@ -125,9 +125,10 @@ struct target_core_fabric_ops {
>>   int target_depend_item(struct config_item *item);
>>   void target_undepend_item(struct config_item *item);
>>   +struct t10_transport_id *target_cp_transport_id(struct
>> t10_transport_id *);
>>   struct se_session *target_setup_session(struct se_portal_group *,
>>           unsigned int, unsigned int, enum target_prot_op prot_op,
>> -        const char *, void *,
>> +        struct t10_transport_id *, const char *, void *,
>>           int (*callback)(struct se_portal_group *,
>>                   struct se_session *, void *));
>>   void target_remove_session(struct se_session *);
>>
> 

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [RFC PATCH 02/12] target: separate acl name from port ids
@ 2020-04-21 17:09       ` Mike Christie
  0 siblings, 0 replies; 38+ messages in thread
From: Mike Christie @ 2020-04-21 17:09 UTC (permalink / raw)
  To: Bodo Stroesser, jsmart2021, bvanassche, martin.petersen,
	linux-scsi, target-devel

On 04/21/2020 09:49 AM, Bodo Stroesser wrote:
> I'm wondering, whether the 'format' element of the new t10_transport_id
> structure is useful:
> 
> - It is used for iSCSI only, but is a common field for all protocols.
> 
> - In iSCSI, if format is 0 then session_id is NULL, and if format is
>   not 0 then session_id is not NULL. So session_id can be used for the
>   same purpose.
> 
> - I think it is a bug that tcm_loop and vhost claim to run iSCSI
>   protocol, but don't deliver an ISID. They e.g. could use the "Random"
>   format for the ISID, which starts with byte 0x80 followed by 3 random
>   bytes and 2 further bytes denoting the session.
> 
> Removing the format element would of course mean to not add the "format"
> session attribute later. (The "session_id" attribute doesn't even check
> format, but uses session_id as argument to "%s" in snprintf even if it
> is NULL).

Yeah, I was just letting it print "NULL" like the other stat file we
have that prints out the isid.

I can just drop format and it will print out "" like the ACL file.

> 
> 
> On 04/20/20 21:14, Mike Christie wrote:
>> To handle features like PGRs in userspace we need the entire iniaitor
>> port id. For iscsi that is defined as the initiator name plus the
>> session identifier. The session id is hidden from users, because
>> its internal to the drivers, so this patch separates the acl name
>> from the SCSI port ids.
>>
>> This will then allow other drivers like SRP to use different values
>> like the port id or src address for the ACL, but then use the port
>> id for transport ID checks in target_core_fabric.c.
>>
>> This will also be used to export the initiator info in the session's
>> sysfs dir in the last patches, so tools like tcmu-runner can rebuild
>> its session state used when handling PGR commands.
>>
>> Signed-off-by: Mike Christie <mchristi@redhat.com>
>> ---
>>   drivers/infiniband/ulp/srpt/ib_srpt.c    | 13 +++--
>>   drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c |  9 +++-
>>   drivers/scsi/qla2xxx/tcm_qla2xxx.c       |  8 ++-
>>   drivers/target/loopback/tcm_loop.c       | 24 ++++++++-
>>   drivers/target/sbp/sbp_target.c          |  9 +++-
>>   drivers/target/target_core_fabric_lib.c  | 87
>> ++++++++++++++++++++++++++++++++
>>   drivers/target/target_core_internal.h    |  1 +
>>   drivers/target/target_core_transport.c   | 22 +++++---
>>   drivers/target/tcm_fc/tfc_sess.c         | 10 +++-
>>   drivers/usb/gadget/function/f_tcm.c      | 11 +++-
>>   drivers/vhost/scsi.c                     | 25 +++++++--
>>   drivers/xen/xen-scsiback.c               | 28 ++++++++--
>>   include/target/target_core_base.h        | 24 +++++++++
>>   include/target/target_core_fabric.h      |  3 +-
>>   14 files changed, 245 insertions(+), 29 deletions(-)
>>
>> diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c
>> b/drivers/infiniband/ulp/srpt/ib_srpt.c
>> index 9855274..caeb32e 100644
>> --- a/drivers/infiniband/ulp/srpt/ib_srpt.c
>> +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
>> @@ -2144,6 +2144,7 @@ static int srpt_cm_req_recv(struct srpt_device
>> *const sdev,
>>                   const char *src_addr)
>>   {
>>       struct srpt_port *sport = &sdev->port[port_num - 1];
>> +    struct t10_transport_id tpid;
>>       struct srpt_nexus *nexus;
>>       struct srp_login_rsp *rsp = NULL;
>>       struct srp_login_rej *rej = NULL;
>> @@ -2314,13 +2315,17 @@ static int srpt_cm_req_recv(struct srpt_device
>> *const sdev,
>>       tag_num = ch->rq_size;
>>       tag_size = 1; /* ib_srpt does not use se_sess->sess_cmd_map */
>>   +    memset(&tpid, 0, sizeof(tpid));
>> +    tpid.proto = SCSI_PROTOCOL_SRP;
>> +    tpid.srp.port_id = i_port_id + 2;
>> +
>>       mutex_lock(&sport->port_guid_id.mutex);
>>       list_for_each_entry(stpg, &sport->port_guid_id.tpg_list, entry) {
>>           if (!IS_ERR_OR_NULL(ch->sess))
>>               break;
>>           ch->sess = target_setup_session(&stpg->tpg, tag_num,
>>                           tag_size, TARGET_PROT_NORMAL,
>> -                        ch->sess_name, ch, NULL);
>> +                        &tpid, ch->sess_name, ch, NULL);
>>       }
>>       mutex_unlock(&sport->port_guid_id.mutex);
>>   @@ -2329,14 +2334,14 @@ static int srpt_cm_req_recv(struct
>> srpt_device *const sdev,
>>           if (!IS_ERR_OR_NULL(ch->sess))
>>               break;
>>           ch->sess = target_setup_session(&stpg->tpg, tag_num,
>> -                    tag_size, TARGET_PROT_NORMAL, i_port_id,
>> -                    ch, NULL);
>> +                    tag_size, TARGET_PROT_NORMAL, &tpid,
>> +                    i_port_id, ch, NULL);
>>           if (!IS_ERR_OR_NULL(ch->sess))
>>               break;
>>           /* Retry without leading "0x" */
>>           ch->sess = target_setup_session(&stpg->tpg, tag_num,
>>                           tag_size, TARGET_PROT_NORMAL,
>> -                        i_port_id + 2, ch, NULL);
>> +                        &tpid, i_port_id + 2, ch, NULL);
>>       }
>>       mutex_unlock(&sport->port_gid_id.mutex);
>>   diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
>> b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
>> index d9e94e8..dba9ec0 100644
>> --- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
>> +++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
>> @@ -2208,6 +2208,7 @@ static int ibmvscsis_make_nexus(struct
>> ibmvscsis_tport *tport)
>>   {
>>       char *name = tport->tport_name;
>>       struct ibmvscsis_nexus *nexus;
>> +    struct t10_transport_id tpid;
>>       struct scsi_info *vscsi = container_of(tport, struct scsi_info,
>> tport);
>>       int rc;
>>   @@ -2222,9 +2223,13 @@ static int ibmvscsis_make_nexus(struct
>> ibmvscsis_tport *tport)
>>           return -ENOMEM;
>>       }
>>   +    memset(&tpid, 0, sizeof(tpid));
>> +    tpid.proto = SCSI_PROTOCOL_SRP;
>> +    tpid.srp.port_id = name;
>> +
>>       nexus->se_sess = target_setup_session(&tport->se_tpg, 0, 0,
>> -                          TARGET_PROT_NORMAL, name, nexus,
>> -                          NULL);
>> +                          TARGET_PROT_NORMAL, &tpid, name,
>> +                          nexus, NULL);
>>       if (IS_ERR(nexus->se_sess)) {
>>           rc = PTR_ERR(nexus->se_sess);
>>           goto transport_init_fail;
>> diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
>> b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
>> index abe7f79..42a4025 100644
>> --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
>> +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
>> @@ -1428,6 +1428,7 @@ static int tcm_qla2xxx_check_initiator_node_acl(
>>   {
>>       struct qla_hw_data *ha = vha->hw;
>>       struct tcm_qla2xxx_lport *lport;
>> +    struct t10_transport_id tpid;
>>       struct tcm_qla2xxx_tpg *tpg;
>>       struct se_session *se_sess;
>>       unsigned char port_name[36];
>> @@ -1454,13 +1455,18 @@ static int tcm_qla2xxx_check_initiator_node_acl(
>>        */
>>       memset(&port_name, 0, 36);
>>       snprintf(port_name, sizeof(port_name), "%8phC", fc_wwpn);
>> +
>> +    memset(&tpid, 0, sizeof(tpid));
>> +    tpid.proto = SCSI_PROTOCOL_FCP;
>> +    tpid.fcp.port_name = port_name;
>> +
>>       /*
>>        * Locate our struct se_node_acl either from an explict NodeACL
>> created
>>        * via ConfigFS, or via running in TPG demo mode.
>>        */
>>       se_sess = target_setup_session(&tpg->se_tpg, num_tags,
>>                          sizeof(struct qla_tgt_cmd),
>> -                       TARGET_PROT_ALL, port_name,
>> +                       TARGET_PROT_ALL, &tpid, port_name,
>>                          qlat_sess, tcm_qla2xxx_session_cb);
>>       if (IS_ERR(se_sess))
>>           return PTR_ERR(se_sess);
>> diff --git a/drivers/target/loopback/tcm_loop.c
>> b/drivers/target/loopback/tcm_loop.c
>> index 3305b47..7593a53 100644
>> --- a/drivers/target/loopback/tcm_loop.c
>> +++ b/drivers/target/loopback/tcm_loop.c
>> @@ -725,10 +725,11 @@ static int tcm_loop_alloc_sess_cb(struct
>> se_portal_group *se_tpg,
>>     static int tcm_loop_make_nexus(
>>       struct tcm_loop_tpg *tl_tpg,
>> -    const char *name)
>> +    char *name)
>>   {
>>       struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
>>       struct tcm_loop_nexus *tl_nexus;
>> +    struct t10_transport_id tpid;
>>       int ret;
>>         if (tl_tpg->tl_nexus) {
>> @@ -736,13 +737,32 @@ static int tcm_loop_make_nexus(
>>           return -EEXIST;
>>       }
>>   +    memset(&tpid, 0, sizeof(tpid));
>> +    tpid.proto = tl_hba->tl_proto_id;
>> +
>> +    switch (tpid.proto) {
>> +    case SCSI_PROTOCOL_SAS:
>> +        tpid.sas.addr = name;
>> +        break;
>> +    case SCSI_PROTOCOL_FCP:
>> +        tpid.fcp.port_name = name;
>> +        break;
>> +    case SCSI_PROTOCOL_ISCSI:
>> +        /* we only support format=0 */
>> +        tpid.iscsi.name = name;
>> +        break;
>> +    default:
>> +        return -EINVAL;
>> +    }
>> +
>>       tl_nexus = kzalloc(sizeof(*tl_nexus), GFP_KERNEL);
>>       if (!tl_nexus)
>>           return -ENOMEM;
>>         tl_nexus->se_sess = target_setup_session(&tl_tpg->tl_se_tpg,
>> 0, 0,
>>                       TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS,
>> -                    name, tl_nexus, tcm_loop_alloc_sess_cb);
>> +                    &tpid, name, tl_nexus,
>> +                    tcm_loop_alloc_sess_cb);
>>       if (IS_ERR(tl_nexus->se_sess)) {
>>           ret = PTR_ERR(tl_nexus->se_sess);
>>           kfree(tl_nexus);
>> diff --git a/drivers/target/sbp/sbp_target.c
>> b/drivers/target/sbp/sbp_target.c
>> index e4a9b9f..9a3121d 100644
>> --- a/drivers/target/sbp/sbp_target.c
>> +++ b/drivers/target/sbp/sbp_target.c
>> @@ -181,6 +181,7 @@ static struct sbp_session *sbp_session_create(
>>           struct sbp_tpg *tpg,
>>           u64 guid)
>>   {
>> +    struct t10_transport_id tpid;
>>       struct sbp_session *sess;
>>       int ret;
>>       char guid_str[17];
>> @@ -196,10 +197,14 @@ static struct sbp_session *sbp_session_create(
>>       INIT_DELAYED_WORK(&sess->maint_work, session_maintenance_work);
>>       sess->guid = guid;
>>   +    memset(&tpid, 0, sizeof(tpid));
>> +    tpid.proto = SCSI_PROTOCOL_SBP;
>> +    tpid.sbp.name = guid_str;
>> +
>>       sess->se_sess = target_setup_session(&tpg->se_tpg, 128,
>>                            sizeof(struct sbp_target_request),
>> -                         TARGET_PROT_NORMAL, guid_str,
>> -                         sess, NULL);
>> +                         TARGET_PROT_NORMAL, &tpid,
>> +                         guid_str, sess, NULL);
>>       if (IS_ERR(sess->se_sess)) {
>>           pr_err("failed to init se_session\n");
>>           ret = PTR_ERR(sess->se_sess);
>> diff --git a/drivers/target/target_core_fabric_lib.c
>> b/drivers/target/target_core_fabric_lib.c
>> index 6b4b354..39b0e5e 100644
>> --- a/drivers/target/target_core_fabric_lib.c
>> +++ b/drivers/target/target_core_fabric_lib.c
>> @@ -421,3 +421,90 @@ const char
>> *target_parse_pr_out_transport_id(struct se_portal_group *tpg,
>>       *out_tid_len = 24;
>>       return buf + offset;
>>   }
>> +
>> +struct t10_transport_id *target_cp_transport_id(struct
>> t10_transport_id *src)
>> +{
>> +    struct t10_transport_id *dst;
>> +
>> +    dst = kzalloc(sizeof(*dst), GFP_KERNEL);
>> +    if (!dst)
>> +        return NULL;
>> +    dst->format = src->format;
>> +    dst->proto = src->proto;
>> +
>> +    switch (src->proto) {
>> +    case SCSI_PROTOCOL_FCP:
>> +        dst->fcp.port_name = kstrdup(src->fcp.port_name, GFP_KERNEL);
>> +        if (!dst->fcp.port_name)
>> +            goto free_tpid;
>> +        break;
>> +    case SCSI_PROTOCOL_SBP:
>> +        dst->sbp.name = kstrdup(src->sbp.name, GFP_KERNEL);
>> +        if (!dst->sbp.name)
>> +            goto free_tpid;
>> +        break;
>> +    case SCSI_PROTOCOL_SRP:
>> +        dst->srp.port_id = kstrdup(src->srp.port_id, GFP_KERNEL);
>> +        if (!dst->srp.port_id)
>> +            goto free_tpid;
>> +        break;
>> +    case SCSI_PROTOCOL_SAS:
>> +        dst->sas.addr = kstrdup(src->sas.addr, GFP_KERNEL);
>> +        if (!dst->sas.addr)
>> +            goto free_tpid;
>> +        break;
>> +    case SCSI_PROTOCOL_ISCSI:
>> +        dst->iscsi.name = kstrdup(src->iscsi.name, GFP_KERNEL);
>> +        if (!dst->iscsi.name)
>> +            goto free_tpid;
>> +
>> +        if (src->format) {
>> +            dst->iscsi.session_id = kstrdup(src->iscsi.session_id,
>> +                            GFP_KERNEL);
>> +            if (!dst->iscsi.session_id) {
>> +                kfree(dst->iscsi.name);
>> +                goto free_tpid;
>> +            }
>> +        }
>> +        break;
>> +    default:
>> +        pr_err("Unknown proto_id: 0x%02x\n", src->proto);
>> +        return NULL;
>> +    }
>> +
>> +    return dst;
>> +
>> +free_tpid:
>> +    kfree(dst);
>> +    return NULL;
>> +}
>> +EXPORT_SYMBOL(target_cp_transport_id);
>> +
>> +void target_free_transport_id(struct t10_transport_id *tpid)
>> +{
>> +    if (!tpid)
>> +        return;
>> +
>> +    switch (tpid->proto) {
>> +    case SCSI_PROTOCOL_FCP:
>> +        kfree(tpid->fcp.port_name);
>> +        break;
>> +    case SCSI_PROTOCOL_SBP:
>> +        kfree(tpid->sbp.name);
>> +        break;
>> +    case SCSI_PROTOCOL_SRP:
>> +        kfree(tpid->srp.port_id);
>> +        break;
>> +    case SCSI_PROTOCOL_SAS:
>> +        kfree(tpid->sas.addr);
>> +        break;
>> +    case SCSI_PROTOCOL_ISCSI:
>> +        kfree(tpid->iscsi.name);
>> +        kfree(tpid->iscsi.session_id);
>> +        break;
>> +    default:
>> +        pr_err("Unknown proto_id: 0x%02x\n", tpid->proto);
>> +        return;
>> +    }
>> +    kfree(tpid);
>> +}
>> diff --git a/drivers/target/target_core_internal.h
>> b/drivers/target/target_core_internal.h
>> index 8533444..5e016aa 100644
>> --- a/drivers/target/target_core_internal.h
>> +++ b/drivers/target/target_core_internal.h
>> @@ -104,6 +104,7 @@ int    target_get_pr_transport_id(struct
>> se_node_acl *nacl,
>>           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);
>> +void target_free_transport_id(struct t10_transport_id *tpid);
>>     /* target_core_hba.c */
>>   struct se_hba *core_alloc_hba(const char *, u32, u32);
>> diff --git a/drivers/target/target_core_transport.c
>> b/drivers/target/target_core_transport.c
>> index 0ae9e60..adf4a84 100644
>> --- a/drivers/target/target_core_transport.c
>> +++ b/drivers/target/target_core_transport.c
>> @@ -416,12 +416,13 @@ void transport_register_session(
>>   struct se_session *
>>   target_setup_session(struct se_portal_group *tpg,
>>                unsigned int tag_num, unsigned int tag_size,
>> -             enum target_prot_op prot_op,
>> +             enum target_prot_op prot_op, struct t10_transport_id *tpid,
>>                const char *initiatorname, void *private,
>>                int (*callback)(struct se_portal_group *,
>>                        struct se_session *, void *))
>>   {
>>       struct se_session *sess;
>> +    int rc;
>>         /*
>>        * If the fabric driver is using percpu-ida based pre allocation
>> @@ -435,6 +436,12 @@ struct se_session *
>>       if (IS_ERR(sess))
>>           return sess;
>>   +    sess->tpid = target_cp_transport_id(tpid);
>> +    if (!sess->tpid) {
>> +        rc = -ENOMEM;
>> +        goto free_sess;
>> +    }
>> +
>>       sess->se_node_acl = core_tpg_check_initiator_node_acl(tpg,
>>                       (unsigned char *)initiatorname);
>>       if (!sess->se_node_acl) {
>> @@ -446,15 +453,17 @@ struct se_session *
>>        * required before transport_register_session().
>>        */
>>       if (callback != NULL) {
>> -        int rc = callback(tpg, sess, private);
>> -        if (rc) {
>> -            transport_free_session(sess);
>> -            return ERR_PTR(rc);
>> -        }
>> +        rc = callback(tpg, sess, private);
>> +        if (rc)
>> +            goto free_sess;
>>       }
>>         transport_register_session(tpg, sess->se_node_acl, sess,
>> private);
>>       return sess;
>> +
>> +free_sess:
>> +    transport_free_session(sess);
>> +    return ERR_PTR(rc);
>>   }
>>   EXPORT_SYMBOL(target_setup_session);
>>   @@ -579,6 +588,7 @@ void transport_free_session(struct se_session
>> *se_sess)
>>           sbitmap_queue_free(&se_sess->sess_tag_pool);
>>           kvfree(se_sess->sess_cmd_map);
>>       }
>> +    target_free_transport_id(se_sess->tpid);
>>       percpu_ref_exit(&se_sess->cmd_count);
>>       kmem_cache_free(se_sess_cache, se_sess);
>>   }
>> diff --git a/drivers/target/tcm_fc/tfc_sess.c
>> b/drivers/target/tcm_fc/tfc_sess.c
>> index 4fd6a1d..f261756 100644
>> --- a/drivers/target/tcm_fc/tfc_sess.c
>> +++ b/drivers/target/tcm_fc/tfc_sess.c
>> @@ -208,6 +208,7 @@ static struct ft_sess *ft_sess_create(struct
>> ft_tport *tport, u32 port_id,
>>                         struct fc_rport_priv *rdata)
>>   {
>>       struct se_portal_group *se_tpg = &tport->tpg->se_tpg;
>> +    struct t10_transport_id tpid;
>>       struct ft_sess *sess;
>>       struct hlist_head *head;
>>       unsigned char initiatorname[TRANSPORT_IQN_LEN];
>> @@ -227,10 +228,15 @@ static struct ft_sess *ft_sess_create(struct
>> ft_tport *tport, u32 port_id,
>>       sess->tport = tport;
>>       sess->port_id = port_id;
>>   +    memset(&tpid, 0, sizeof(tpid));
>> +    tpid.proto = SCSI_PROTOCOL_FCP;
>> +    tpid.fcp.port_name = &initiatorname[0];
>> +
>>       sess->se_sess = target_setup_session(se_tpg, TCM_FC_DEFAULT_TAGS,
>>                            sizeof(struct ft_cmd),
>> -                         TARGET_PROT_NORMAL, &initiatorname[0],
>> -                         sess, ft_sess_alloc_cb);
>> +                         TARGET_PROT_NORMAL, &tpid,
>> +                         &initiatorname[0], sess,
>> +                         ft_sess_alloc_cb);
>>       if (IS_ERR(sess->se_sess)) {
>>           int rc = PTR_ERR(sess->se_sess);
>>           kfree(sess);
>> diff --git a/drivers/usb/gadget/function/f_tcm.c
>> b/drivers/usb/gadget/function/f_tcm.c
>> index 3650493..e282eb9 100644
>> --- a/drivers/usb/gadget/function/f_tcm.c
>> +++ b/drivers/usb/gadget/function/f_tcm.c
>> @@ -1564,6 +1564,7 @@ static int usbg_alloc_sess_cb(struct
>> se_portal_group *se_tpg,
>>   static int tcm_usbg_make_nexus(struct usbg_tpg *tpg, char *name)
>>   {
>>       struct tcm_usbg_nexus *tv_nexus;
>> +    struct t10_transport_id tpid;
>>       int ret = 0;
>>         mutex_lock(&tpg->tpg_mutex);
>> @@ -1579,11 +1580,17 @@ static int tcm_usbg_make_nexus(struct usbg_tpg
>> *tpg, char *name)
>>           goto out_unlock;
>>       }
>>   +    memset(&tpid, 0, sizeof(tpid));
>> +    tpid.proto = tpg->se_tpg.proto_id;
>> +    /* SPC does not assign a proto id for USB-SCSI so we use SAS
>> naming */
>> +    tpid.sas.addr = name;
>> +
>>       tv_nexus->tvn_se_sess = target_setup_session(&tpg->se_tpg,
>>                                USB_G_DEFAULT_SESSION_TAGS,
>>                                sizeof(struct usbg_cmd),
>> -                             TARGET_PROT_NORMAL, name,
>> -                             tv_nexus, usbg_alloc_sess_cb);
>> +                             TARGET_PROT_NORMAL, &tpid,
>> +                             name, tv_nexus,
>> +                             usbg_alloc_sess_cb);
>>       if (IS_ERR(tv_nexus->tvn_se_sess)) {
>>   #define MAKE_NEXUS_MSG "core_tpg_check_initiator_node_acl() failed
>> for %s\n"
>>           pr_debug(MAKE_NEXUS_MSG, name);
>> diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
>> index 0b949a1..bc377ee 100644
>> --- a/drivers/vhost/scsi.c
>> +++ b/drivers/vhost/scsi.c
>> @@ -1937,10 +1937,10 @@ static int vhost_scsi_nexus_cb(struct
>> se_portal_group *se_tpg,
>>       return -ENOMEM;
>>   }
>>   -static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg,
>> -                const char *name)
>> +static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg, char *name)
>>   {
>>       struct vhost_scsi_nexus *tv_nexus;
>> +    struct t10_transport_id tpid;
>>         mutex_lock(&tpg->tv_tpg_mutex);
>>       if (tpg->tpg_nexus) {
>> @@ -1949,6 +1949,25 @@ static int vhost_scsi_make_nexus(struct
>> vhost_scsi_tpg *tpg,
>>           return -EEXIST;
>>       }
>>   +    memset(&tpid, 0, sizeof(tpid));
>> +    tpid.proto = tpg->se_tpg.proto_id;
>> +
>> +    switch (tpid.proto) {
>> +    case SCSI_PROTOCOL_SAS:
>> +        tpid.sas.addr = name;
>> +        break;
>> +    case SCSI_PROTOCOL_FCP:
>> +        tpid.fcp.port_name = name;
>> +        break;
>> +    case SCSI_PROTOCOL_ISCSI:
>> +        /* we only support format=0 */
>> +        tpid.iscsi.name = name;
>> +        break;
>> +    default:
>> +        mutex_unlock(&tpg->tv_tpg_mutex);
>> +        return -EINVAL;
>> +    }
>> +
>>       tv_nexus = kzalloc(sizeof(*tv_nexus), GFP_KERNEL);
>>       if (!tv_nexus) {
>>           mutex_unlock(&tpg->tv_tpg_mutex);
>> @@ -1964,7 +1983,7 @@ static int vhost_scsi_make_nexus(struct
>> vhost_scsi_tpg *tpg,
>>                       VHOST_SCSI_DEFAULT_TAGS,
>>                       sizeof(struct vhost_scsi_cmd),
>>                       TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS,
>> -                    (unsigned char *)name, tv_nexus,
>> +                    &tpid, (unsigned char *)name, tv_nexus,
>>                       vhost_scsi_nexus_cb);
>>       if (IS_ERR(tv_nexus->tvn_se_sess)) {
>>           mutex_unlock(&tpg->tv_tpg_mutex);
>> diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
>> index ba0942e..0855a77f 100644
>> --- a/drivers/xen/xen-scsiback.c
>> +++ b/drivers/xen/xen-scsiback.c
>> @@ -1507,10 +1507,10 @@ static int scsiback_alloc_sess_cb(struct
>> se_portal_group *se_tpg,
>>       return 0;
>>   }
>>   -static int scsiback_make_nexus(struct scsiback_tpg *tpg,
>> -                const char *name)
>> +static int scsiback_make_nexus(struct scsiback_tpg *tpg, char *name)
>>   {
>>       struct scsiback_nexus *tv_nexus;
>> +    struct t10_transport_id tpid;
>>       int ret = 0;
>>         mutex_lock(&tpg->tv_tpg_mutex);
>> @@ -1520,6 +1520,25 @@ static int scsiback_make_nexus(struct
>> scsiback_tpg *tpg,
>>           goto out_unlock;
>>       }
>>   +    memset(&tpid, 0, sizeof(tpid));
>> +    tpid.proto = tpg->se_tpg.proto_id;
>> +
>> +    switch (tpid.proto) {
>> +    case SCSI_PROTOCOL_SAS:
>> +        tpid.sas.addr = name;
>> +        break;
>> +    case SCSI_PROTOCOL_FCP:
>> +        tpid.fcp.port_name = name;
>> +        break;
>> +    case SCSI_PROTOCOL_ISCSI:
>> +        /* we only support format=0 */
>> +        tpid.iscsi.name = name;
>> +        break;
>> +    default:
>> +        ret =-EINVAL;
>> +        goto out_unlock;
>> +    }
>> +
>>       tv_nexus = kzalloc(sizeof(struct scsiback_nexus), GFP_KERNEL);
>>       if (!tv_nexus) {
>>           ret = -ENOMEM;
>> @@ -1529,8 +1548,9 @@ static int scsiback_make_nexus(struct
>> scsiback_tpg *tpg,
>>       tv_nexus->tvn_se_sess = target_setup_session(&tpg->se_tpg,
>>                                VSCSI_DEFAULT_SESSION_TAGS,
>>                                sizeof(struct vscsibk_pend),
>> -                             TARGET_PROT_NORMAL, name,
>> -                             tv_nexus, scsiback_alloc_sess_cb);
>> +                             TARGET_PROT_NORMAL, &tpid,
>> +                             name, tv_nexus,
>> +                             scsiback_alloc_sess_cb);
>>       if (IS_ERR(tv_nexus->tvn_se_sess)) {
>>           kfree(tv_nexus);
>>           ret = -ENOMEM;
>> diff --git a/include/target/target_core_base.h
>> b/include/target/target_core_base.h
>> index 1728e88..cd440ea 100644
>> --- a/include/target/target_core_base.h
>> +++ b/include/target/target_core_base.h
>> @@ -333,6 +333,29 @@ struct t10_wwn {
>>       struct list_head t10_vpd_list;
>>   };
>>   +struct t10_transport_id {
>> +    union {
>> +        struct {
>> +            char *port_name;
>> +        } fcp;
>> +        struct {
>> +            char *addr;
>> +        } sas;
>> +        struct {
>> +            char *name;
>> +        } sbp;
>> +        struct {
>> +            char *port_id;
>> +        } srp;
>> +        struct {
>> +            char *name;
>> +            char *session_id;
>> +        } iscsi;
>> +    };
>> +    u8 format;
>> +    u8 proto;
>> +};
>> +
>>   struct t10_pr_registration {
>>       /* Used for fabrics that contain WWN+ISID */
>>   #define PR_REG_ISID_LEN                16
>> @@ -605,6 +628,7 @@ static inline struct se_node_acl
>> *fabric_stat_to_nacl(struct config_item *item)
>>   struct se_session {
>>       unsigned        sess_tearing_down:1;
>>       u64            sess_bin_isid;
>> +    struct t10_transport_id    *tpid;
>>       enum target_prot_op    sup_prot_ops;
>>       enum target_prot_type    sess_prot_type;
>>       struct se_node_acl    *se_node_acl;
>> diff --git a/include/target/target_core_fabric.h
>> b/include/target/target_core_fabric.h
>> index 063f133..6b8a6bc 100644
>> --- a/include/target/target_core_fabric.h
>> +++ b/include/target/target_core_fabric.h
>> @@ -125,9 +125,10 @@ struct target_core_fabric_ops {
>>   int target_depend_item(struct config_item *item);
>>   void target_undepend_item(struct config_item *item);
>>   +struct t10_transport_id *target_cp_transport_id(struct
>> t10_transport_id *);
>>   struct se_session *target_setup_session(struct se_portal_group *,
>>           unsigned int, unsigned int, enum target_prot_op prot_op,
>> -        const char *, void *,
>> +        struct t10_transport_id *, const char *, void *,
>>           int (*callback)(struct se_portal_group *,
>>                   struct se_session *, void *));
>>   void target_remove_session(struct se_session *);
>>
> 


^ permalink raw reply	[flat|nested] 38+ messages in thread

end of thread, other threads:[~2020-04-21 17:10 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-20 19:14 RFC PATCH 00/12] target: add sysfs support Mike Christie
2020-04-20 19:14 ` Mike Christie
2020-04-20 19:14 ` [RFC PATCH 01/12] target: check enforce_pr_isids during registration Mike Christie
2020-04-20 19:14   ` Mike Christie
2020-04-20 19:14 ` [RFC PATCH 02/12] target: separate acl name from port ids Mike Christie
2020-04-20 19:14   ` Mike Christie
2020-04-21 14:49   ` Bodo Stroesser
2020-04-21 14:49     ` Bodo Stroesser
2020-04-21 17:09     ` Mike Christie
2020-04-21 17:09       ` Mike Christie
2020-04-20 19:14 ` [RFC PATCH 03/12] iscsi target: setup transport_id Mike Christie
2020-04-20 19:14   ` Mike Christie
2020-04-20 19:14 ` [RFC PATCH 04/12] target: use tpid in target_stat_iport_port_ident_show Mike Christie
2020-04-20 19:14   ` Mike Christie
2020-04-21 14:58   ` Bodo Stroesser
2020-04-21 14:58     ` Bodo Stroesser
2020-04-20 19:14 ` [RFC PATCH 05/12] target: drop sess_get_initiator_sid from PR code Mike Christie
2020-04-20 19:14   ` Mike Christie
2020-04-20 19:14 ` [RFC PATCH 06/12] target: drop sess_get_initiator_sid Mike Christie
2020-04-20 19:14   ` Mike Christie
2020-04-20 19:14 ` [RFC PATCH 07/12] target: add sysfs support Mike Christie
2020-04-20 19:14   ` Mike Christie
2020-04-21 15:48   ` Bodo Stroesser
2020-04-21 15:48     ` Bodo Stroesser
2020-04-20 19:14 ` [RFC PATCH 08/12] target: add sysfs session helper functions Mike Christie
2020-04-20 19:14   ` Mike Christie
2020-04-21 16:07   ` Bodo Stroesser
2020-04-21 16:07     ` Bodo Stroesser
2020-04-20 19:14 ` [RFC PATCH 09/12] target: move session setup cb to fabric ops Mike Christie
2020-04-20 19:14   ` Mike Christie
2020-04-20 19:14 ` [RFC PATCH 10/12] target: add target_setup_session sysfs support Mike Christie
2020-04-20 19:14   ` Mike Christie
2020-04-20 19:14 ` [RFC PATCH 11/12] iscsi target: use session sysfs helpers Mike Christie
2020-04-20 19:14   ` Mike Christie
2020-04-21 16:26   ` Bodo Stroesser
2020-04-21 16:26     ` Bodo Stroesser
2020-04-20 19:14 ` [RFC PATCH 12/12] target: drop sess_get_index Mike Christie
2020-04-20 19:14   ` Mike Christie

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.