mirror of
https://github.com/torvalds/linux.git
synced 2024-12-27 05:11:48 +00:00
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: Christoph Hellwig <hch@lst.de> Cc: Sagi Grimberg <sagig@mellanox.com> Cc: Christoph Hellwig <hch@lst.de> Cc: Hannes Reinecke <hare@suse.de> Cc: Andy Grover <agrover@redhat.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
parent
81f70ba233
commit
7861728d42
@ -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,
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user