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 <bart.vanassche@sandisk.com>.
(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 <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
diff --git a/Documentation/target/tcm_mod_builder.py b/Documentation/target/tcm_mod_builder.py
index 2b47704..27afc03 100755
--- a/Documentation/target/tcm_mod_builder.py
+++ b/Documentation/target/tcm_mod_builder.py
@@ -237,8 +237,7 @@
buf += "#include \"" + fabric_mod_name + "_base.h\"\n"
buf += "#include \"" + fabric_mod_name + "_fabric.h\"\n\n"
- buf += "/* Local pointer to allocated TCM configfs fabric module */\n"
- buf += "struct target_fabric_configfs *" + fabric_mod_name + "_fabric_configfs;\n\n"
+ buf += "static const struct target_core_fabric_ops " + fabric_mod_name + "_ops;\n\n"
buf += "static struct se_node_acl *" + fabric_mod_name + "_make_nodeacl(\n"
buf += " struct se_portal_group *se_tpg,\n"
@@ -309,8 +308,8 @@
buf += " }\n"
buf += " tpg->" + fabric_mod_port + " = " + fabric_mod_port + ";\n"
buf += " tpg->" + fabric_mod_port + "_tpgt = tpgt;\n\n"
- buf += " ret = core_tpg_register(&" + fabric_mod_name + "_fabric_configfs->tf_ops, wwn,\n"
- buf += " &tpg->se_tpg, (void *)tpg,\n"
+ buf += " ret = core_tpg_register(&" + fabric_mod_name + "_ops, wwn,\n"
+ buf += " &tpg->se_tpg, tpg,\n"
buf += " TRANSPORT_TPG_TYPE_NORMAL);\n"
buf += " if (ret < 0) {\n"
buf += " kfree(tpg);\n"
@@ -370,7 +369,10 @@
buf += " NULL,\n"
buf += "};\n\n"
- buf += "static struct target_core_fabric_ops " + fabric_mod_name + "_ops = {\n"
+ buf += "static const struct target_core_fabric_ops " + fabric_mod_name + "_ops = {\n"
+ buf += " .module = THIS_MODULE\n",
+ buf += " .name = " + fabric_mod_name + ",\n"
+ buf += " .get_fabric_proto_ident = " + fabric_mod_name + "_get_fabric_proto_ident,\n"
buf += " .get_fabric_name = " + fabric_mod_name + "_get_fabric_name,\n"
buf += " .get_fabric_proto_ident = " + fabric_mod_name + "_get_fabric_proto_ident,\n"
buf += " .tpg_get_wwn = " + fabric_mod_name + "_get_fabric_wwn,\n"
@@ -413,75 +415,18 @@
buf += " .fabric_drop_np = NULL,\n"
buf += " .fabric_make_nodeacl = " + fabric_mod_name + "_make_nodeacl,\n"
buf += " .fabric_drop_nodeacl = " + fabric_mod_name + "_drop_nodeacl,\n"
- buf += "};\n\n"
-
- buf += "static int " + fabric_mod_name + "_register_configfs(void)\n"
- buf += "{\n"
- buf += " struct target_fabric_configfs *fabric;\n"
- buf += " int ret;\n\n"
- buf += " printk(KERN_INFO \"" + fabric_mod_name.upper() + " fabric module %s on %s/%s\"\n"
- buf += " \" on \"UTS_RELEASE\"\\n\"," + fabric_mod_name.upper() + "_VERSION, utsname()->sysname,\n"
- buf += " utsname()->machine);\n"
- buf += " /*\n"
- buf += " * Register the top level struct config_item_type with TCM core\n"
- buf += " */\n"
- buf += " fabric = target_fabric_configfs_init(THIS_MODULE, \"" + fabric_mod_name + "\");\n"
- buf += " if (IS_ERR(fabric)) {\n"
- buf += " printk(KERN_ERR \"target_fabric_configfs_init() failed\\n\");\n"
- buf += " return PTR_ERR(fabric);\n"
- buf += " }\n"
- buf += " /*\n"
- buf += " * Setup fabric->tf_ops from our local " + fabric_mod_name + "_ops\n"
- buf += " */\n"
- buf += " fabric->tf_ops = " + fabric_mod_name + "_ops;\n"
- buf += " /*\n"
- buf += " * Setup default attribute lists for various fabric->tf_cit_tmpl\n"
- buf += " */\n"
- buf += " fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = " + fabric_mod_name + "_wwn_attrs;\n"
- buf += " fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = NULL;\n"
- buf += " fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = NULL;\n"
- buf += " fabric->tf_cit_tmpl.tfc_tpg_param_cit.ct_attrs = NULL;\n"
- buf += " fabric->tf_cit_tmpl.tfc_tpg_np_base_cit.ct_attrs = NULL;\n"
- buf += " fabric->tf_cit_tmpl.tfc_tpg_nacl_base_cit.ct_attrs = NULL;\n"
- buf += " fabric->tf_cit_tmpl.tfc_tpg_nacl_attrib_cit.ct_attrs = NULL;\n"
- buf += " fabric->tf_cit_tmpl.tfc_tpg_nacl_auth_cit.ct_attrs = NULL;\n"
- buf += " fabric->tf_cit_tmpl.tfc_tpg_nacl_param_cit.ct_attrs = NULL;\n"
- buf += " /*\n"
- buf += " * Register the fabric for use within TCM\n"
- buf += " */\n"
- buf += " ret = target_fabric_configfs_register(fabric);\n"
- buf += " if (ret < 0) {\n"
- buf += " printk(KERN_ERR \"target_fabric_configfs_register() failed\"\n"
- buf += " \" for " + fabric_mod_name.upper() + "\\n\");\n"
- buf += " return ret;\n"
- buf += " }\n"
- buf += " /*\n"
- buf += " * Setup our local pointer to *fabric\n"
- buf += " */\n"
- buf += " " + fabric_mod_name + "_fabric_configfs = fabric;\n"
- buf += " printk(KERN_INFO \"" + fabric_mod_name.upper() + "[0] - Set fabric -> " + fabric_mod_name + "_fabric_configfs\\n\");\n"
- buf += " return 0;\n"
- buf += "};\n\n"
- buf += "static void __exit " + fabric_mod_name + "_deregister_configfs(void)\n"
- buf += "{\n"
- buf += " if (!" + fabric_mod_name + "_fabric_configfs)\n"
- buf += " return;\n\n"
- buf += " target_fabric_configfs_deregister(" + fabric_mod_name + "_fabric_configfs);\n"
- buf += " " + fabric_mod_name + "_fabric_configfs = NULL;\n"
- buf += " printk(KERN_INFO \"" + fabric_mod_name.upper() + "[0] - Cleared " + fabric_mod_name + "_fabric_configfs\\n\");\n"
+ buf += "\n"
+ buf += " .tfc_wwn_attrs = " + fabric_mod_name + "_wwn_attrs;\n"
buf += "};\n\n"
buf += "static int __init " + fabric_mod_name + "_init(void)\n"
buf += "{\n"
- buf += " int ret;\n\n"
- buf += " ret = " + fabric_mod_name + "_register_configfs();\n"
- buf += " if (ret < 0)\n"
- buf += " return ret;\n\n"
- buf += " return 0;\n"
+ buf += " return target_register_template(" + fabric_mod_name + "_ops);\n"
buf += "};\n\n"
+
buf += "static void __exit " + fabric_mod_name + "_exit(void)\n"
buf += "{\n"
- buf += " " + fabric_mod_name + "_deregister_configfs();\n"
+ buf += " target_unregister_template(" + fabric_mod_name + "_ops);\n"
buf += "};\n\n"
buf += "MODULE_DESCRIPTION(\"" + fabric_mod_name.upper() + " series fabric driver\");\n"