aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2016-01-09 08:29:24 -0500
committerNicholas Bellinger <nab@linux-iscsi.org>2016-02-27 17:59:42 -0500
commit7861728d42338e1efac9d400c39319c1b5efd05c (patch)
tree61e2af681747125dddf84fab7082ded53eabe37f
parent81f70ba233d5f660e1ea5fe23260ee323af5d53a (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.c56
-rw-r--r--include/target/target_core_fabric.h6
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}
375EXPORT_SYMBOL(transport_register_session); 386EXPORT_SYMBOL(transport_register_session);
376 387
388struct se_session *
389target_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}
431EXPORT_SYMBOL(target_alloc_session);
432
377static void target_release_session(struct kref *kref) 433static 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);
108int target_depend_item(struct config_item *item); 108int target_depend_item(struct config_item *item);
109void target_undepend_item(struct config_item *item); 109void target_undepend_item(struct config_item *item);
110 110
111struct 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
111struct se_session *transport_init_session(enum target_prot_op); 117struct se_session *transport_init_session(enum target_prot_op);
112int transport_alloc_session_tags(struct se_session *, unsigned int, 118int transport_alloc_session_tags(struct se_session *, unsigned int,
113 unsigned int); 119 unsigned int);