@@ -2320,7 +2320,8 @@ 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,
- ch->sess_name, ch, NULL);
+ i_port_id + 2, ch->sess_name,
+ ch, NULL);
}
mutex_unlock(&sport->port_guid_id.mutex);
@@ -2329,14 +2330,15 @@ 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,
+ i_port_id + 2, 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);
+ i_port_id + 2, i_port_id + 2,
+ ch, NULL);
}
mutex_unlock(&sport->port_gid_id.mutex);
@@ -2223,8 +2223,8 @@ static int ibmvscsis_make_nexus(struct ibmvscsis_tport *tport)
}
nexus->se_sess = target_setup_session(&tport->se_tpg, 0, 0,
- TARGET_PROT_NORMAL, name, nexus,
- NULL);
+ TARGET_PROT_NORMAL, name, name,
+ nexus, NULL);
if (IS_ERR(nexus->se_sess)) {
rc = PTR_ERR(nexus->se_sess);
goto transport_init_fail;
@@ -1483,7 +1483,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, port_name,
+ TARGET_PROT_ALL, port_name, port_name,
qlat_sess, tcm_qla2xxx_session_cb);
if (IS_ERR(se_sess))
return PTR_ERR(se_sess);
@@ -742,7 +742,8 @@ 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,
- name, tl_nexus, tcm_loop_alloc_sess_cb);
+ name, 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);
@@ -199,7 +199,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, guid_str,
- sess, NULL);
+ guid_str, sess, NULL);
if (IS_ERR(sess->se_sess)) {
pr_err("failed to init se_session\n");
ret = PTR_ERR(sess->se_sess);
@@ -422,3 +422,44 @@ 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_create_transport_id(u8 proto, const char *name,
+ const char *session_id)
+{
+ struct t10_transport_id *tpt_id;
+
+ tpt_id = kzalloc(sizeof(*tpt_id), GFP_KERNEL);
+ if (!tpt_id)
+ return NULL;
+ tpt_id->proto = proto;
+
+ tpt_id->name = kstrdup(name, GFP_KERNEL);
+ if (!tpt_id->name)
+ goto free_tpt_id;
+
+ if (session_id) {
+ tpt_id->session_id = kstrdup(session_id, GFP_KERNEL);
+ if (!tpt_id->session_id)
+ goto free_name;
+ }
+
+ return tpt_id;
+
+free_name:
+ kfree(tpt_id->name);
+free_tpt_id:
+ kfree(tpt_id);
+ return NULL;
+}
+EXPORT_SYMBOL(target_create_transport_id);
+
+void target_free_transport_id(struct t10_transport_id *tpt_id)
+{
+ if (!tpt_id)
+ return;
+
+ kfree(tpt_id->name);
+ kfree(tpt_id->session_id);
+ kfree(tpt_id);
+}
+EXPORT_SYMBOL(target_free_transport_id);
@@ -413,15 +413,27 @@ void transport_register_session(
}
EXPORT_SYMBOL(transport_register_session);
+/**
+ * target_setup_session - alloc and add a session to lio core
+ * @tpg: parent tpg
+ * @tag_num: if non-zero max num in-flight commands.
+ * @tag_size: if tag_num is non-zero, fabric driver's per cmd data in bytes.
+ * @prot_op: bitmask that defines which T10-PI modes are supported.
+ * @tpt_id_name: SCSI TransportID name/address/identifier
+ * @acl_name: name used for se_node_acl
+ * @private: storage for fabric driver accessible via fabric_sess_ptr
+ * @callback: opt function called before session has been added to lio core.
+ */
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,
- const char *initiatorname, void *private,
+ enum target_prot_op prot_op, const char *tpt_id_name,
+ const char *acl_name, 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,26 +447,35 @@ struct se_session *
if (IS_ERR(sess))
return sess;
+ sess->tpt_id = target_create_transport_id(tpg->proto_id, tpt_id_name,
+ NULL);
+ if (!sess->tpt_id) {
+ rc = -ENOMEM;
+ goto free_sess;
+ }
+
sess->se_node_acl = core_tpg_check_initiator_node_acl(tpg,
- (unsigned char *)initiatorname);
+ (unsigned char *)acl_name);
if (!sess->se_node_acl) {
- transport_free_session(sess);
- return ERR_PTR(-EACCES);
+ rc = -EACCES;
+ goto free_sess;
}
/*
* Go ahead and perform any remaining fabric setup that is
* 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 +600,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->tpt_id);
percpu_ref_exit(&se_sess->cmd_count);
kmem_cache_free(se_sess_cache, se_sess);
}
@@ -230,7 +230,8 @@ 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, &initiatorname[0],
- sess, ft_sess_alloc_cb);
+ &initiatorname[0], sess,
+ ft_sess_alloc_cb);
if (IS_ERR(sess->se_sess)) {
int rc = PTR_ERR(sess->se_sess);
kfree(sess);
@@ -1583,7 +1583,8 @@ static int tcm_usbg_make_nexus(struct usbg_tpg *tpg, char *name)
USB_G_DEFAULT_SESSION_TAGS,
sizeof(struct usbg_cmd),
TARGET_PROT_NORMAL, name,
- tv_nexus, usbg_alloc_sess_cb);
+ 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);
@@ -1964,6 +1964,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,
(unsigned char *)name, tv_nexus,
vhost_scsi_nexus_cb);
if (IS_ERR(tv_nexus->tvn_se_sess)) {
@@ -1531,7 +1531,8 @@ static int scsiback_make_nexus(struct scsiback_tpg *tpg,
VSCSI_DEFAULT_SESSION_TAGS,
sizeof(struct vscsibk_pend),
TARGET_PROT_NORMAL, name,
- tv_nexus, scsiback_alloc_sess_cb);
+ name, tv_nexus,
+ scsiback_alloc_sess_cb);
if (IS_ERR(tv_nexus->tvn_se_sess)) {
kfree(tv_nexus);
ret = -ENOMEM;
@@ -331,6 +331,17 @@ struct t10_wwn {
struct list_head t10_vpd_list;
};
+struct t10_transport_id {
+ /* The format=0 transport specific port id/name value. */
+ char *name;
+ /*
+ * If proto is iSCSI and it's using format=1, then this is set to the
+ * initiator session id string defined in spc4r37 table 508.
+ */
+ char *session_id;
+ u8 proto;
+};
+
struct t10_pr_registration {
/* Used for fabrics that contain WWN+ISID */
#define PR_REG_ISID_LEN 16
@@ -610,6 +621,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 *tpt_id;
enum target_prot_op sup_prot_ops;
enum target_prot_type sess_prot_type;
struct se_node_acl *se_node_acl;
@@ -125,9 +125,12 @@ 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_create_transport_id(u8, const char *,
+ const char *);
+void target_free_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 *,
+ const char *, const char *, void *,
int (*callback)(struct se_portal_group *,
struct se_session *, void *));
void target_remove_session(struct se_session *);