From 6e1a27b919c643a1570885425d639f77f04d8690 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 26 Mar 2015 12:27:32 +0100 Subject: target: mark tcm_loop_primary static Signed-off-by: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- drivers/target/loopback/tcm_loop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/target/loopback') diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 6b3c32954689..f4618e722187 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -108,7 +108,7 @@ static struct device_driver tcm_loop_driverfs = { /* * Used with root_device_register() in tcm_loop_alloc_core_bus() below */ -struct device *tcm_loop_primary; +static struct device *tcm_loop_primary; static void tcm_loop_submission_work(struct work_struct *work) { -- cgit v1.2.3 From 436f4a0a99520623ef3fb994d70d2938fc9f00b6 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Sun, 8 Feb 2015 12:31:39 -0800 Subject: loopback: Add fabric_prot_type attribute support This patch updates loopback to add a new fabric_prot_type TPG attribute, used for controlling LLD level protection into LIO when the backend device does not support T10-PI. Also, go ahead and set DIN_PASS + DOUT_PASS so target-core knows that it will be doing any WRITE_STRIP and READ_INSERT operations. Cc: Martin Petersen Cc: Sagi Grimberg Cc: Hannes Reinecke Signed-off-by: Nicholas Bellinger --- drivers/target/loopback/tcm_loop.c | 54 ++++++++++++++++++++++++++++++++++++-- drivers/target/loopback/tcm_loop.h | 1 + 2 files changed, 53 insertions(+), 2 deletions(-) (limited to 'drivers/target/loopback') diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index f4618e722187..797c7315f520 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -697,6 +697,13 @@ static int tcm_loop_check_prod_mode_write_protect(struct se_portal_group *se_tpg return 0; } +static int tcm_loop_check_prot_fabric_only(struct se_portal_group *se_tpg) +{ + struct tcm_loop_tpg *tl_tpg = container_of(se_tpg, struct tcm_loop_tpg, + tl_se_tpg); + return tl_tpg->tl_fabric_prot_type; +} + static struct se_node_acl *tcm_loop_tpg_alloc_fabric_acl( struct se_portal_group *se_tpg) { @@ -912,6 +919,46 @@ static void tcm_loop_port_unlink( /* End items for tcm_loop_port_cit */ +static ssize_t tcm_loop_tpg_attrib_show_fabric_prot_type( + struct se_portal_group *se_tpg, + char *page) +{ + struct tcm_loop_tpg *tl_tpg = container_of(se_tpg, struct tcm_loop_tpg, + tl_se_tpg); + + return sprintf(page, "%d\n", tl_tpg->tl_fabric_prot_type); +} + +static ssize_t tcm_loop_tpg_attrib_store_fabric_prot_type( + struct se_portal_group *se_tpg, + const char *page, + size_t count) +{ + struct tcm_loop_tpg *tl_tpg = container_of(se_tpg, struct tcm_loop_tpg, + tl_se_tpg); + unsigned long val; + int ret = kstrtoul(page, 0, &val); + + if (ret) { + pr_err("kstrtoul() returned %d for fabric_prot_type\n", ret); + return ret; + } + if (val != 0 && val != 1 && val != 3) { + pr_err("Invalid qla2xxx fabric_prot_type: %lu\n", val); + return -EINVAL; + } + tl_tpg->tl_fabric_prot_type = val; + + return count; +} + +TF_TPG_ATTRIB_ATTR(tcm_loop, fabric_prot_type, S_IRUGO | S_IWUSR); + +static struct configfs_attribute *tcm_loop_tpg_attrib_attrs[] = { + &tcm_loop_tpg_attrib_fabric_prot_type.attr, + NULL, +}; + /* Start items for tcm_loop_nexus_cit */ static int tcm_loop_make_nexus( @@ -937,7 +984,8 @@ static int tcm_loop_make_nexus( /* * Initialize the struct se_session pointer */ - tl_nexus->se_sess = transport_init_session(TARGET_PROT_ALL); + tl_nexus->se_sess = transport_init_session( + TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS); if (IS_ERR(tl_nexus->se_sess)) { ret = PTR_ERR(tl_nexus->se_sess); goto out; @@ -1377,6 +1425,8 @@ static int tcm_loop_register_configfs(void) &tcm_loop_check_demo_mode_write_protect; fabric->tf_ops.tpg_check_prod_mode_write_protect = &tcm_loop_check_prod_mode_write_protect; + fabric->tf_ops.tpg_check_prot_fabric_only = + &tcm_loop_check_prot_fabric_only; /* * The TCM loopback fabric module runs in demo-mode to a local * virtual SCSI device, so fabric dependent initator ACLs are @@ -1429,7 +1479,7 @@ static int tcm_loop_register_configfs(void) */ fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = tcm_loop_wwn_attrs; fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = tcm_loop_tpg_attrs; - fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = NULL; + fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = tcm_loop_tpg_attrib_attrs; fabric->tf_cit_tmpl.tfc_tpg_param_cit.ct_attrs = NULL; fabric->tf_cit_tmpl.tfc_tpg_np_base_cit.ct_attrs = NULL; /* diff --git a/drivers/target/loopback/tcm_loop.h b/drivers/target/loopback/tcm_loop.h index 6ae49f272ba6..1e72ff77cac9 100644 --- a/drivers/target/loopback/tcm_loop.h +++ b/drivers/target/loopback/tcm_loop.h @@ -43,6 +43,7 @@ struct tcm_loop_nacl { struct tcm_loop_tpg { unsigned short tl_tpgt; unsigned short tl_transport_status; + enum target_prot_type tl_fabric_prot_type; atomic_t tl_tpg_port_count; struct se_portal_group tl_se_tpg; struct tcm_loop_hba *tl_hba; -- cgit v1.2.3 From 2e1cd90d718a5fc721e0caa0dc9f037d9b1f46b8 Mon Sep 17 00:00:00 2001 From: Ming Lin Date: Sun, 29 Mar 2015 23:11:30 -0700 Subject: tcm_loop: fixup tpgt string to integer conversion Currently, for example, mkdir "tpgt_xyz" doesn't return error. mkdir /sys/kernel/config/target/loopback/naa.60014055f195952b/tpgt_xyz Replace obsoleted simple_strtoul with kstrtoul and check the conversion. Signed-off-by: Ming Lin Signed-off-by: Nicholas Bellinger --- drivers/target/loopback/tcm_loop.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers/target/loopback') diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 797c7315f520..2114c1d2c9de 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -1216,21 +1216,19 @@ static struct se_portal_group *tcm_loop_make_naa_tpg( struct tcm_loop_hba *tl_hba = container_of(wwn, struct tcm_loop_hba, tl_hba_wwn); struct tcm_loop_tpg *tl_tpg; - char *tpgt_str, *end_ptr; int ret; - unsigned short int tpgt; + unsigned long tpgt; - tpgt_str = strstr(name, "tpgt_"); - if (!tpgt_str) { + if (strstr(name, "tpgt_") != name) { pr_err("Unable to locate \"tpgt_#\" directory" " group\n"); return ERR_PTR(-EINVAL); } - tpgt_str += 5; /* Skip ahead of "tpgt_" */ - tpgt = (unsigned short int) simple_strtoul(tpgt_str, &end_ptr, 0); + if (kstrtoul(name+5, 10, &tpgt)) + return ERR_PTR(-EINVAL); if (tpgt >= TL_TPGS_PER_HBA) { - pr_err("Passed tpgt: %hu exceeds TL_TPGS_PER_HBA:" + pr_err("Passed tpgt: %lu exceeds TL_TPGS_PER_HBA:" " %u\n", tpgt, TL_TPGS_PER_HBA); return ERR_PTR(-EINVAL); } @@ -1247,7 +1245,7 @@ static struct se_portal_group *tcm_loop_make_naa_tpg( return ERR_PTR(-ENOMEM); pr_debug("TCM_Loop_ConfigFS: Allocated Emulated %s" - " Target Port %s,t,0x%04x\n", tcm_loop_dump_proto_id(tl_hba), + " Target Port %s,t,0x%04lx\n", tcm_loop_dump_proto_id(tl_hba), config_item_name(&wwn->wwn_group.cg_item), tpgt); return &tl_tpg->tl_se_tpg; -- cgit v1.2.3 From 9ac8928e6a3e1ed02e632e45aa766129fe6b1802 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 8 Apr 2015 20:01:35 +0200 Subject: target: simplify the target template registration API Instead of calling target_fabric_configfs_init() + target_fabric_configfs_register() / target_fabric_configfs_deregister() target_fabric_configfs_free() from every target driver, rewrite the API so that we have simple register/unregister functions that operate on a const operations vector. This patch also fixes a memory leak in several target drivers. Several target drivers namely called target_fabric_configfs_deregister() without calling target_fabric_configfs_free(). A large part of this patch is based on earlier changes from Bart Van Assche . (v2: Add a new TF_CIT_SETUP_DRV macro so that the core configfs code can declare attributes as either core only or for drivers) Signed-off-by: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- drivers/target/loopback/tcm_loop.c | 178 ++++++++++--------------------------- 1 file changed, 49 insertions(+), 129 deletions(-) (limited to 'drivers/target/loopback') diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 2114c1d2c9de..5b143d2c08f7 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -41,8 +41,7 @@ #define to_tcm_loop_hba(hba) container_of(hba, struct tcm_loop_hba, dev) -/* Local pointer to allocated TCM configfs fabric module */ -static struct target_fabric_configfs *tcm_loop_fabric_configfs; +static const struct target_core_fabric_ops loop_ops; static struct workqueue_struct *tcm_loop_workqueue; static struct kmem_cache *tcm_loop_cmd_cache; @@ -1238,8 +1237,7 @@ static struct se_portal_group *tcm_loop_make_naa_tpg( /* * Register the tl_tpg as a emulated SAS TCM Target Endpoint */ - ret = core_tpg_register(&tcm_loop_fabric_configfs->tf_ops, - wwn, &tl_tpg->tl_se_tpg, tl_tpg, + ret = core_tpg_register(&loop_ops, wwn, &tl_tpg->tl_se_tpg, tl_tpg, TRANSPORT_TPG_TYPE_NORMAL); if (ret < 0) return ERR_PTR(-ENOMEM); @@ -1387,129 +1385,51 @@ static struct configfs_attribute *tcm_loop_wwn_attrs[] = { /* End items for tcm_loop_cit */ -static int tcm_loop_register_configfs(void) -{ - struct target_fabric_configfs *fabric; - int ret; - /* - * Set the TCM Loop HBA counter to zero - */ - tcm_loop_hba_no_cnt = 0; - /* - * Register the top level struct config_item_type with TCM core - */ - fabric = target_fabric_configfs_init(THIS_MODULE, "loopback"); - if (IS_ERR(fabric)) { - pr_err("tcm_loop_register_configfs() failed!\n"); - return PTR_ERR(fabric); - } - /* - * Setup the fabric API of function pointers used by target_core_mod - */ - fabric->tf_ops.get_fabric_name = &tcm_loop_get_fabric_name; - fabric->tf_ops.get_fabric_proto_ident = &tcm_loop_get_fabric_proto_ident; - fabric->tf_ops.tpg_get_wwn = &tcm_loop_get_endpoint_wwn; - fabric->tf_ops.tpg_get_tag = &tcm_loop_get_tag; - fabric->tf_ops.tpg_get_default_depth = &tcm_loop_get_default_depth; - fabric->tf_ops.tpg_get_pr_transport_id = &tcm_loop_get_pr_transport_id; - fabric->tf_ops.tpg_get_pr_transport_id_len = - &tcm_loop_get_pr_transport_id_len; - fabric->tf_ops.tpg_parse_pr_out_transport_id = - &tcm_loop_parse_pr_out_transport_id; - fabric->tf_ops.tpg_check_demo_mode = &tcm_loop_check_demo_mode; - fabric->tf_ops.tpg_check_demo_mode_cache = - &tcm_loop_check_demo_mode_cache; - fabric->tf_ops.tpg_check_demo_mode_write_protect = - &tcm_loop_check_demo_mode_write_protect; - fabric->tf_ops.tpg_check_prod_mode_write_protect = - &tcm_loop_check_prod_mode_write_protect; - fabric->tf_ops.tpg_check_prot_fabric_only = - &tcm_loop_check_prot_fabric_only; - /* - * The TCM loopback fabric module runs in demo-mode to a local - * virtual SCSI device, so fabric dependent initator ACLs are - * not required. - */ - fabric->tf_ops.tpg_alloc_fabric_acl = &tcm_loop_tpg_alloc_fabric_acl; - fabric->tf_ops.tpg_release_fabric_acl = - &tcm_loop_tpg_release_fabric_acl; - fabric->tf_ops.tpg_get_inst_index = &tcm_loop_get_inst_index; - /* - * Used for setting up remaining TCM resources in process context - */ - fabric->tf_ops.check_stop_free = &tcm_loop_check_stop_free; - fabric->tf_ops.release_cmd = &tcm_loop_release_cmd; - fabric->tf_ops.shutdown_session = &tcm_loop_shutdown_session; - fabric->tf_ops.close_session = &tcm_loop_close_session; - fabric->tf_ops.sess_get_index = &tcm_loop_sess_get_index; - fabric->tf_ops.sess_get_initiator_sid = NULL; - fabric->tf_ops.write_pending = &tcm_loop_write_pending; - fabric->tf_ops.write_pending_status = &tcm_loop_write_pending_status; - /* - * Not used for TCM loopback - */ - fabric->tf_ops.set_default_node_attributes = - &tcm_loop_set_default_node_attributes; - fabric->tf_ops.get_task_tag = &tcm_loop_get_task_tag; - fabric->tf_ops.get_cmd_state = &tcm_loop_get_cmd_state; - fabric->tf_ops.queue_data_in = &tcm_loop_queue_data_in; - fabric->tf_ops.queue_status = &tcm_loop_queue_status; - fabric->tf_ops.queue_tm_rsp = &tcm_loop_queue_tm_rsp; - fabric->tf_ops.aborted_task = &tcm_loop_aborted_task; - - /* - * Setup function pointers for generic logic in target_core_fabric_configfs.c - */ - fabric->tf_ops.fabric_make_wwn = &tcm_loop_make_scsi_hba; - fabric->tf_ops.fabric_drop_wwn = &tcm_loop_drop_scsi_hba; - fabric->tf_ops.fabric_make_tpg = &tcm_loop_make_naa_tpg; - fabric->tf_ops.fabric_drop_tpg = &tcm_loop_drop_naa_tpg; - /* - * fabric_post_link() and fabric_pre_unlink() are used for - * registration and release of TCM Loop Virtual SCSI LUNs. - */ - fabric->tf_ops.fabric_post_link = &tcm_loop_port_link; - fabric->tf_ops.fabric_pre_unlink = &tcm_loop_port_unlink; - fabric->tf_ops.fabric_make_np = NULL; - fabric->tf_ops.fabric_drop_np = NULL; - /* - * Setup default attribute lists for various fabric->tf_cit_tmpl - */ - fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = tcm_loop_wwn_attrs; - fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = tcm_loop_tpg_attrs; - fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = tcm_loop_tpg_attrib_attrs; - fabric->tf_cit_tmpl.tfc_tpg_param_cit.ct_attrs = NULL; - fabric->tf_cit_tmpl.tfc_tpg_np_base_cit.ct_attrs = NULL; - /* - * Once fabric->tf_ops has been setup, now register the fabric for - * use within TCM - */ - ret = target_fabric_configfs_register(fabric); - if (ret < 0) { - pr_err("target_fabric_configfs_register() for" - " TCM_Loop failed!\n"); - target_fabric_configfs_free(fabric); - return -1; - } - /* - * Setup our local pointer to *fabric. - */ - tcm_loop_fabric_configfs = fabric; - pr_debug("TCM_LOOP[0] - Set fabric ->" - " tcm_loop_fabric_configfs\n"); - return 0; -} - -static void tcm_loop_deregister_configfs(void) -{ - if (!tcm_loop_fabric_configfs) - return; - - target_fabric_configfs_deregister(tcm_loop_fabric_configfs); - tcm_loop_fabric_configfs = NULL; - pr_debug("TCM_LOOP[0] - Cleared" - " tcm_loop_fabric_configfs\n"); -} +static const struct target_core_fabric_ops loop_ops = { + .module = THIS_MODULE, + .name = "loopback", + .get_fabric_name = tcm_loop_get_fabric_name, + .get_fabric_proto_ident = tcm_loop_get_fabric_proto_ident, + .tpg_get_wwn = tcm_loop_get_endpoint_wwn, + .tpg_get_tag = tcm_loop_get_tag, + .tpg_get_default_depth = tcm_loop_get_default_depth, + .tpg_get_pr_transport_id = tcm_loop_get_pr_transport_id, + .tpg_get_pr_transport_id_len = tcm_loop_get_pr_transport_id_len, + .tpg_parse_pr_out_transport_id = tcm_loop_parse_pr_out_transport_id, + .tpg_check_demo_mode = tcm_loop_check_demo_mode, + .tpg_check_demo_mode_cache = tcm_loop_check_demo_mode_cache, + .tpg_check_demo_mode_write_protect = + tcm_loop_check_demo_mode_write_protect, + .tpg_check_prod_mode_write_protect = + tcm_loop_check_prod_mode_write_protect, + .tpg_check_prot_fabric_only = tcm_loop_check_prot_fabric_only, + .tpg_alloc_fabric_acl = tcm_loop_tpg_alloc_fabric_acl, + .tpg_release_fabric_acl = tcm_loop_tpg_release_fabric_acl, + .tpg_get_inst_index = tcm_loop_get_inst_index, + .check_stop_free = tcm_loop_check_stop_free, + .release_cmd = tcm_loop_release_cmd, + .shutdown_session = tcm_loop_shutdown_session, + .close_session = tcm_loop_close_session, + .sess_get_index = tcm_loop_sess_get_index, + .write_pending = tcm_loop_write_pending, + .write_pending_status = tcm_loop_write_pending_status, + .set_default_node_attributes = tcm_loop_set_default_node_attributes, + .get_task_tag = tcm_loop_get_task_tag, + .get_cmd_state = tcm_loop_get_cmd_state, + .queue_data_in = tcm_loop_queue_data_in, + .queue_status = tcm_loop_queue_status, + .queue_tm_rsp = tcm_loop_queue_tm_rsp, + .aborted_task = tcm_loop_aborted_task, + .fabric_make_wwn = tcm_loop_make_scsi_hba, + .fabric_drop_wwn = tcm_loop_drop_scsi_hba, + .fabric_make_tpg = tcm_loop_make_naa_tpg, + .fabric_drop_tpg = tcm_loop_drop_naa_tpg, + .fabric_post_link = tcm_loop_port_link, + .fabric_pre_unlink = tcm_loop_port_unlink, + .tfc_wwn_attrs = tcm_loop_wwn_attrs, + .tfc_tpg_base_attrs = tcm_loop_tpg_attrs, + .tfc_tpg_attrib_attrs = tcm_loop_tpg_attrib_attrs, +}; static int __init tcm_loop_fabric_init(void) { @@ -1533,7 +1453,7 @@ static int __init tcm_loop_fabric_init(void) if (ret) goto out_destroy_cache; - ret = tcm_loop_register_configfs(); + ret = target_register_template(&loop_ops); if (ret) goto out_release_core_bus; @@ -1551,7 +1471,7 @@ out: static void __exit tcm_loop_fabric_exit(void) { - tcm_loop_deregister_configfs(); + target_unregister_template(&loop_ops); tcm_loop_release_core_bus(); kmem_cache_destroy(tcm_loop_cmd_cache); destroy_workqueue(tcm_loop_workqueue); -- cgit v1.2.3