|
@@ -232,6 +232,50 @@ struct se_session *transport_init_session(void)
|
|
|
}
|
|
|
EXPORT_SYMBOL(transport_init_session);
|
|
|
|
|
|
+int transport_alloc_session_tags(struct se_session *se_sess,
|
|
|
+ unsigned int tag_num, unsigned int tag_size)
|
|
|
+{
|
|
|
+ int rc;
|
|
|
+
|
|
|
+ se_sess->sess_cmd_map = kzalloc(tag_num * tag_size, GFP_KERNEL);
|
|
|
+ if (!se_sess->sess_cmd_map) {
|
|
|
+ pr_err("Unable to allocate se_sess->sess_cmd_map\n");
|
|
|
+ return -ENOMEM;
|
|
|
+ }
|
|
|
+
|
|
|
+ rc = percpu_ida_init(&se_sess->sess_tag_pool, tag_num);
|
|
|
+ if (rc < 0) {
|
|
|
+ pr_err("Unable to init se_sess->sess_tag_pool,"
|
|
|
+ " tag_num: %u\n", tag_num);
|
|
|
+ kfree(se_sess->sess_cmd_map);
|
|
|
+ se_sess->sess_cmd_map = NULL;
|
|
|
+ return -ENOMEM;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(transport_alloc_session_tags);
|
|
|
+
|
|
|
+struct se_session *transport_init_session_tags(unsigned int tag_num,
|
|
|
+ unsigned int tag_size)
|
|
|
+{
|
|
|
+ struct se_session *se_sess;
|
|
|
+ int rc;
|
|
|
+
|
|
|
+ se_sess = transport_init_session();
|
|
|
+ if (IS_ERR(se_sess))
|
|
|
+ return se_sess;
|
|
|
+
|
|
|
+ rc = transport_alloc_session_tags(se_sess, tag_num, tag_size);
|
|
|
+ if (rc < 0) {
|
|
|
+ transport_free_session(se_sess);
|
|
|
+ return ERR_PTR(-ENOMEM);
|
|
|
+ }
|
|
|
+
|
|
|
+ return se_sess;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(transport_init_session_tags);
|
|
|
+
|
|
|
/*
|
|
|
* Called with spin_lock_irqsave(&struct se_portal_group->session_lock called.
|
|
|
*/
|
|
@@ -367,6 +411,10 @@ EXPORT_SYMBOL(transport_deregister_session_configfs);
|
|
|
|
|
|
void transport_free_session(struct se_session *se_sess)
|
|
|
{
|
|
|
+ if (se_sess->sess_cmd_map) {
|
|
|
+ percpu_ida_destroy(&se_sess->sess_tag_pool);
|
|
|
+ kfree(se_sess->sess_cmd_map);
|
|
|
+ }
|
|
|
kmem_cache_free(se_sess_cache, se_sess);
|
|
|
}
|
|
|
EXPORT_SYMBOL(transport_free_session);
|