diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2016-01-09 08:29:24 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2016-02-27 17:59:42 -0500 |
commit | 7861728d42338e1efac9d400c39319c1b5efd05c (patch) | |
tree | 61e2af681747125dddf84fab7082ded53eabe37f | |
parent | 81f70ba233d5f660e1ea5fe23260ee323af5d53a (diff) |
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>
-rw-r--r-- | drivers/target/target_core_transport.c | 56 | ||||
-rw-r--r-- | include/target/target_core_fabric.h | 6 |
2 files changed, 62 insertions, 0 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 867bc6d0a68a..f5ad9e063b65 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -281,6 +281,17 @@ struct se_session *transport_init_session_tags(unsigned int tag_num, | |||
281 | struct se_session *se_sess; | 281 | struct se_session *se_sess; |
282 | int rc; | 282 | int rc; |
283 | 283 | ||
284 | if (tag_num != 0 && !tag_size) { | ||
285 | pr_err("init_session_tags called with percpu-ida tag_num:" | ||
286 | " %u, but zero tag_size\n", tag_num); | ||
287 | return ERR_PTR(-EINVAL); | ||
288 | } | ||
289 | if (!tag_num && tag_size) { | ||
290 | pr_err("init_session_tags called with percpu-ida tag_size:" | ||
291 | " %u, but zero tag_num\n", tag_size); | ||
292 | return ERR_PTR(-EINVAL); | ||
293 | } | ||
294 | |||
284 | se_sess = transport_init_session(sup_prot_ops); | 295 | se_sess = transport_init_session(sup_prot_ops); |
285 | if (IS_ERR(se_sess)) | 296 | if (IS_ERR(se_sess)) |
286 | return se_sess; | 297 | return se_sess; |
@@ -374,6 +385,51 @@ void transport_register_session( | |||
374 | } | 385 | } |
375 | EXPORT_SYMBOL(transport_register_session); | 386 | EXPORT_SYMBOL(transport_register_session); |
376 | 387 | ||
388 | struct se_session * | ||
389 | target_alloc_session(struct se_portal_group *tpg, | ||
390 | unsigned int tag_num, unsigned int tag_size, | ||
391 | enum target_prot_op prot_op, | ||
392 | const char *initiatorname, void *private, | ||
393 | int (*callback)(struct se_portal_group *, | ||
394 | struct se_session *, void *)) | ||
395 | { | ||
396 | struct se_session *sess; | ||
397 | |||
398 | /* | ||
399 | * If the fabric driver is using percpu-ida based pre allocation | ||
400 | * of I/O descriptor tags, go ahead and perform that setup now.. | ||
401 | */ | ||
402 | if (tag_num != 0) | ||
403 | sess = transport_init_session_tags(tag_num, tag_size, prot_op); | ||
404 | else | ||
405 | sess = transport_init_session(prot_op); | ||
406 | |||
407 | if (IS_ERR(sess)) | ||
408 | return sess; | ||
409 | |||
410 | sess->se_node_acl = core_tpg_check_initiator_node_acl(tpg, | ||
411 | (unsigned char *)initiatorname); | ||
412 | if (!sess->se_node_acl) { | ||
413 | transport_free_session(sess); | ||
414 | return ERR_PTR(-EACCES); | ||
415 | } | ||
416 | /* | ||
417 | * Go ahead and perform any remaining fabric setup that is | ||
418 | * required before transport_register_session(). | ||
419 | */ | ||
420 | if (callback != NULL) { | ||
421 | int rc = callback(tpg, sess, private); | ||
422 | if (rc) { | ||
423 | transport_free_session(sess); | ||
424 | return ERR_PTR(rc); | ||
425 | } | ||
426 | } | ||
427 | |||
428 | transport_register_session(tpg, sess->se_node_acl, sess, private); | ||
429 | return sess; | ||
430 | } | ||
431 | EXPORT_SYMBOL(target_alloc_session); | ||
432 | |||
377 | static void target_release_session(struct kref *kref) | 433 | static void target_release_session(struct kref *kref) |
378 | { | 434 | { |
379 | struct se_session *se_sess = container_of(kref, | 435 | struct se_session *se_sess = container_of(kref, |
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index 56653408f53b..685a51aa98cc 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h | |||
@@ -108,6 +108,12 @@ void target_unregister_template(const struct target_core_fabric_ops *fo); | |||
108 | int target_depend_item(struct config_item *item); | 108 | int target_depend_item(struct config_item *item); |
109 | void target_undepend_item(struct config_item *item); | 109 | void target_undepend_item(struct config_item *item); |
110 | 110 | ||
111 | struct se_session *target_alloc_session(struct se_portal_group *, | ||
112 | unsigned int, unsigned int, enum target_prot_op prot_op, | ||
113 | const char *, void *, | ||
114 | int (*callback)(struct se_portal_group *, | ||
115 | struct se_session *, void *)); | ||
116 | |||
111 | struct se_session *transport_init_session(enum target_prot_op); | 117 | struct se_session *transport_init_session(enum target_prot_op); |
112 | int transport_alloc_session_tags(struct se_session *, unsigned int, | 118 | int transport_alloc_session_tags(struct se_session *, unsigned int, |
113 | unsigned int); | 119 | unsigned int); |