|
@@ -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(
|
|
|
}
|
|
|
EXPORT_SYMBOL(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);
|
|
|
+ else
|
|
|
+ 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) {
|
|
|
+ transport_free_session(sess);
|
|
|
+ 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) {
|
|
|
+ transport_free_session(sess);
|
|
|
+ return ERR_PTR(rc);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ transport_register_session(tpg, sess->se_node_acl, sess, private);
|
|
|
+ return sess;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(target_alloc_session);
|
|
|
+
|
|
|
static void target_release_session(struct kref *kref)
|
|
|
{
|
|
|
struct se_session *se_sess = container_of(kref,
|