Commit 7861728d authored by Nicholas Bellinger's avatar Nicholas Bellinger

target: Add target_alloc_session() helper function

Based on HCH's original patch, this adds a full version to
support percpu-ida tag pre-allocation and callback function
pointer into fabric driver code to complete session setup.
Reported-by: default avatarChristoph Hellwig <>
Cc: Sagi Grimberg <>
Cc: Christoph Hellwig <>
Cc: Hannes Reinecke <>
Cc: Andy Grover <>
Signed-off-by: default avatarNicholas Bellinger <>
parent 81f70ba2
......@@ -281,6 +281,17 @@ struct se_session *transport_init_session_tags(unsigned int tag_num,
struct se_session *se_sess;
int rc;
if (tag_num != 0 && !tag_size) {
pr_err("init_session_tags called with percpu-ida tag_num:"
" %u, but zero tag_size\n", tag_num);
return ERR_PTR(-EINVAL);
if (!tag_num && tag_size) {
pr_err("init_session_tags called with percpu-ida tag_size:"
" %u, but zero tag_num\n", tag_size);
return ERR_PTR(-EINVAL);
se_sess = transport_init_session(sup_prot_ops);
if (IS_ERR(se_sess))
return se_sess;
......@@ -374,6 +385,51 @@ void transport_register_session(
struct se_session *
target_alloc_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,
int (*callback)(struct se_portal_group *,
struct se_session *, void *))
struct se_session *sess;
* If the fabric driver is using percpu-ida based pre allocation
* of I/O descriptor tags, go ahead and perform that setup now..
if (tag_num != 0)
sess = transport_init_session_tags(tag_num, tag_size, prot_op);
sess = transport_init_session(prot_op);
if (IS_ERR(sess))
return sess;
sess->se_node_acl = core_tpg_check_initiator_node_acl(tpg,
(unsigned char *)initiatorname);
if (!sess->se_node_acl) {
return ERR_PTR(-EACCES);
* 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) {
return ERR_PTR(rc);
transport_register_session(tpg, sess->se_node_acl, sess, private);
return sess;
static void target_release_session(struct kref *kref)
struct se_session *se_sess = container_of(kref,
......@@ -108,6 +108,12 @@ void target_unregister_template(const struct target_core_fabric_ops *fo);
int target_depend_item(struct config_item *item);
void target_undepend_item(struct config_item *item);
struct se_session *target_alloc_session(struct se_portal_group *,
unsigned int, unsigned int, enum target_prot_op prot_op,
const char *, void *,
int (*callback)(struct se_portal_group *,
struct se_session *, void *));
struct se_session *transport_init_session(enum target_prot_op);
int transport_alloc_session_tags(struct se_session *, unsigned int,
unsigned int);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment