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>
This commit is contained in:
		
							parent
							
								
									2c336e3a2e
								
							
						
					
					
						commit
						9ac8928e6a
					
				| @ -237,8 +237,7 @@ def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name): | ||||
| 	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 @@ def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name): | ||||
| 	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 @@ def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name): | ||||
| 	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 @@ def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name): | ||||
| 	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" | ||||
|  | ||||
| @ -93,7 +93,7 @@ MODULE_PARM_DESC(srpt_service_guid, | ||||
| 		 " instead of using the node_guid of the first HCA."); | ||||
| 
 | ||||
| static struct ib_client srpt_client; | ||||
| static struct target_fabric_configfs *srpt_target; | ||||
| static const struct target_core_fabric_ops srpt_template; | ||||
| static void srpt_release_channel(struct srpt_rdma_ch *ch); | ||||
| static int srpt_queue_status(struct se_cmd *cmd); | ||||
| 
 | ||||
| @ -3851,7 +3851,7 @@ static struct se_portal_group *srpt_make_tpg(struct se_wwn *wwn, | ||||
| 	int res; | ||||
| 
 | ||||
| 	/* Initialize sport->port_wwn and sport->port_tpg_1 */ | ||||
| 	res = core_tpg_register(&srpt_target->tf_ops, &sport->port_wwn, | ||||
| 	res = core_tpg_register(&srpt_template, &sport->port_wwn, | ||||
| 			&sport->port_tpg_1, sport, TRANSPORT_TPG_TYPE_NORMAL); | ||||
| 	if (res) | ||||
| 		return ERR_PTR(res); | ||||
| @ -3919,7 +3919,9 @@ static struct configfs_attribute *srpt_wwn_attrs[] = { | ||||
| 	NULL, | ||||
| }; | ||||
| 
 | ||||
| static struct target_core_fabric_ops srpt_template = { | ||||
| static const struct target_core_fabric_ops srpt_template = { | ||||
| 	.module				= THIS_MODULE, | ||||
| 	.name				= "srpt", | ||||
| 	.get_fabric_name		= srpt_get_fabric_name, | ||||
| 	.get_fabric_proto_ident		= srpt_get_fabric_proto_ident, | ||||
| 	.tpg_get_wwn			= srpt_get_fabric_wwn, | ||||
| @ -3964,6 +3966,10 @@ static struct target_core_fabric_ops srpt_template = { | ||||
| 	.fabric_drop_np			= NULL, | ||||
| 	.fabric_make_nodeacl		= srpt_make_nodeacl, | ||||
| 	.fabric_drop_nodeacl		= srpt_drop_nodeacl, | ||||
| 
 | ||||
| 	.tfc_wwn_attrs			= srpt_wwn_attrs, | ||||
| 	.tfc_tpg_base_attrs		= srpt_tpg_attrs, | ||||
| 	.tfc_tpg_attrib_attrs		= srpt_tpg_attrib_attrs, | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
| @ -3994,33 +4000,9 @@ static int __init srpt_init_module(void) | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	srpt_target = target_fabric_configfs_init(THIS_MODULE, "srpt"); | ||||
| 	if (IS_ERR(srpt_target)) { | ||||
| 		printk(KERN_ERR "couldn't register\n"); | ||||
| 		ret = PTR_ERR(srpt_target); | ||||
| 	ret = target_register_template(&srpt_template); | ||||
| 	if (ret) | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	srpt_target->tf_ops = srpt_template; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Set up default attribute lists. | ||||
| 	 */ | ||||
| 	srpt_target->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = srpt_wwn_attrs; | ||||
| 	srpt_target->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = srpt_tpg_attrs; | ||||
| 	srpt_target->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = srpt_tpg_attrib_attrs; | ||||
| 	srpt_target->tf_cit_tmpl.tfc_tpg_param_cit.ct_attrs = NULL; | ||||
| 	srpt_target->tf_cit_tmpl.tfc_tpg_np_base_cit.ct_attrs = NULL; | ||||
| 	srpt_target->tf_cit_tmpl.tfc_tpg_nacl_base_cit.ct_attrs = NULL; | ||||
| 	srpt_target->tf_cit_tmpl.tfc_tpg_nacl_attrib_cit.ct_attrs = NULL; | ||||
| 	srpt_target->tf_cit_tmpl.tfc_tpg_nacl_auth_cit.ct_attrs = NULL; | ||||
| 	srpt_target->tf_cit_tmpl.tfc_tpg_nacl_param_cit.ct_attrs = NULL; | ||||
| 
 | ||||
| 	ret = target_fabric_configfs_register(srpt_target); | ||||
| 	if (ret < 0) { | ||||
| 		printk(KERN_ERR "couldn't register\n"); | ||||
| 		goto out_free_target; | ||||
| 	} | ||||
| 
 | ||||
| 	ret = ib_register_client(&srpt_client); | ||||
| 	if (ret) { | ||||
| @ -4031,11 +4013,7 @@ static int __init srpt_init_module(void) | ||||
| 	return 0; | ||||
| 
 | ||||
| out_unregister_target: | ||||
| 	target_fabric_configfs_deregister(srpt_target); | ||||
| 	srpt_target = NULL; | ||||
| out_free_target: | ||||
| 	if (srpt_target) | ||||
| 		target_fabric_configfs_free(srpt_target); | ||||
| 	target_unregister_template(&srpt_template); | ||||
| out: | ||||
| 	return ret; | ||||
| } | ||||
| @ -4043,8 +4021,7 @@ out: | ||||
| static void __exit srpt_cleanup_module(void) | ||||
| { | ||||
| 	ib_unregister_client(&srpt_client); | ||||
| 	target_fabric_configfs_deregister(srpt_target); | ||||
| 	srpt_target = NULL; | ||||
| 	target_unregister_template(&srpt_template); | ||||
| } | ||||
| 
 | ||||
| module_init(srpt_init_module); | ||||
|  | ||||
| @ -3065,7 +3065,7 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle, | ||||
| { | ||||
| 	struct qla_hw_data *ha = vha->hw; | ||||
| 	struct se_cmd *se_cmd; | ||||
| 	struct target_core_fabric_ops *tfo; | ||||
| 	const struct target_core_fabric_ops *tfo; | ||||
| 	struct qla_tgt_cmd *cmd; | ||||
| 
 | ||||
| 	if (handle & CTIO_INTERMEDIATE_HANDLE_MARK) { | ||||
|  | ||||
| @ -53,9 +53,8 @@ | ||||
| static struct workqueue_struct *tcm_qla2xxx_free_wq; | ||||
| static struct workqueue_struct *tcm_qla2xxx_cmd_wq; | ||||
| 
 | ||||
| /* Local pointer to allocated TCM configfs fabric module */ | ||||
| static struct target_fabric_configfs *tcm_qla2xxx_fabric_configfs; | ||||
| static struct target_fabric_configfs *tcm_qla2xxx_npiv_fabric_configfs; | ||||
| static const struct target_core_fabric_ops tcm_qla2xxx_ops; | ||||
| static const struct target_core_fabric_ops tcm_qla2xxx_npiv_ops; | ||||
| 
 | ||||
| /*
 | ||||
|  * Parse WWN. | ||||
| @ -1177,7 +1176,7 @@ static struct se_portal_group *tcm_qla2xxx_make_tpg( | ||||
| 	tpg->tpg_attrib.cache_dynamic_acls = 1; | ||||
| 	tpg->tpg_attrib.demo_mode_login_only = 1; | ||||
| 
 | ||||
| 	ret = core_tpg_register(&tcm_qla2xxx_fabric_configfs->tf_ops, wwn, | ||||
| 	ret = core_tpg_register(&tcm_qla2xxx_ops, wwn, | ||||
| 				&tpg->se_tpg, tpg, TRANSPORT_TPG_TYPE_NORMAL); | ||||
| 	if (ret < 0) { | ||||
| 		kfree(tpg); | ||||
| @ -1297,7 +1296,7 @@ static struct se_portal_group *tcm_qla2xxx_npiv_make_tpg( | ||||
| 	tpg->tpg_attrib.cache_dynamic_acls = 1; | ||||
| 	tpg->tpg_attrib.demo_mode_login_only = 1; | ||||
| 
 | ||||
| 	ret = core_tpg_register(&tcm_qla2xxx_npiv_fabric_configfs->tf_ops, wwn, | ||||
| 	ret = core_tpg_register(&tcm_qla2xxx_npiv_ops, wwn, | ||||
| 				&tpg->se_tpg, tpg, TRANSPORT_TPG_TYPE_NORMAL); | ||||
| 	if (ret < 0) { | ||||
| 		kfree(tpg); | ||||
| @ -1987,7 +1986,9 @@ static struct configfs_attribute *tcm_qla2xxx_wwn_attrs[] = { | ||||
| 	NULL, | ||||
| }; | ||||
| 
 | ||||
| static struct target_core_fabric_ops tcm_qla2xxx_ops = { | ||||
| static const struct target_core_fabric_ops tcm_qla2xxx_ops = { | ||||
| 	.module				= THIS_MODULE, | ||||
| 	.name				= "qla2xxx", | ||||
| 	.get_fabric_name		= tcm_qla2xxx_get_fabric_name, | ||||
| 	.get_fabric_proto_ident		= tcm_qla2xxx_get_fabric_proto_ident, | ||||
| 	.tpg_get_wwn			= tcm_qla2xxx_get_fabric_wwn, | ||||
| @ -2037,9 +2038,15 @@ static struct target_core_fabric_ops tcm_qla2xxx_ops = { | ||||
| 	.fabric_drop_np			= NULL, | ||||
| 	.fabric_make_nodeacl		= tcm_qla2xxx_make_nodeacl, | ||||
| 	.fabric_drop_nodeacl		= tcm_qla2xxx_drop_nodeacl, | ||||
| 
 | ||||
| 	.tfc_wwn_attrs			= tcm_qla2xxx_wwn_attrs, | ||||
| 	.tfc_tpg_base_attrs		= tcm_qla2xxx_tpg_attrs, | ||||
| 	.tfc_tpg_attrib_attrs		= tcm_qla2xxx_tpg_attrib_attrs, | ||||
| }; | ||||
| 
 | ||||
| static struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = { | ||||
| static const struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = { | ||||
| 	.module				= THIS_MODULE, | ||||
| 	.name				= "qla2xxx_npiv", | ||||
| 	.get_fabric_name		= tcm_qla2xxx_npiv_get_fabric_name, | ||||
| 	.get_fabric_proto_ident		= tcm_qla2xxx_get_fabric_proto_ident, | ||||
| 	.tpg_get_wwn			= tcm_qla2xxx_get_fabric_wwn, | ||||
| @ -2087,94 +2094,26 @@ static struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = { | ||||
| 	.fabric_drop_np			= NULL, | ||||
| 	.fabric_make_nodeacl		= tcm_qla2xxx_make_nodeacl, | ||||
| 	.fabric_drop_nodeacl		= tcm_qla2xxx_drop_nodeacl, | ||||
| 
 | ||||
| 	.tfc_wwn_attrs			= tcm_qla2xxx_wwn_attrs, | ||||
| 	.tfc_tpg_base_attrs		= tcm_qla2xxx_npiv_tpg_attrs, | ||||
| }; | ||||
| 
 | ||||
| static int tcm_qla2xxx_register_configfs(void) | ||||
| { | ||||
| 	struct target_fabric_configfs *fabric, *npiv_fabric; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	pr_debug("TCM QLOGIC QLA2XXX fabric module %s on %s/%s on " | ||||
| 	    UTS_RELEASE"\n", TCM_QLA2XXX_VERSION, utsname()->sysname, | ||||
| 	    utsname()->machine); | ||||
| 	/*
 | ||||
| 	 * Register the top level struct config_item_type with TCM core | ||||
| 	 */ | ||||
| 	fabric = target_fabric_configfs_init(THIS_MODULE, "qla2xxx"); | ||||
| 	if (IS_ERR(fabric)) { | ||||
| 		pr_err("target_fabric_configfs_init() failed\n"); | ||||
| 		return PTR_ERR(fabric); | ||||
| 	} | ||||
| 	/*
 | ||||
| 	 * Setup fabric->tf_ops from our local tcm_qla2xxx_ops | ||||
| 	 */ | ||||
| 	fabric->tf_ops = tcm_qla2xxx_ops; | ||||
| 	/*
 | ||||
| 	 * Setup default attribute lists for various fabric->tf_cit_tmpl | ||||
| 	 */ | ||||
| 	fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = tcm_qla2xxx_wwn_attrs; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = tcm_qla2xxx_tpg_attrs; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = | ||||
| 						tcm_qla2xxx_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; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_base_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_attrib_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_auth_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_param_cit.ct_attrs = NULL; | ||||
| 	/*
 | ||||
| 	 * Register the fabric for use within TCM | ||||
| 	 */ | ||||
| 	ret = target_fabric_configfs_register(fabric); | ||||
| 	if (ret < 0) { | ||||
| 		pr_err("target_fabric_configfs_register() failed for TCM_QLA2XXX\n"); | ||||
| 		return ret; | ||||
| 	} | ||||
| 	/*
 | ||||
| 	 * Setup our local pointer to *fabric | ||||
| 	 */ | ||||
| 	tcm_qla2xxx_fabric_configfs = fabric; | ||||
| 	pr_debug("TCM_QLA2XXX[0] - Set fabric -> tcm_qla2xxx_fabric_configfs\n"); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Register the top level struct config_item_type for NPIV with TCM core | ||||
| 	 */ | ||||
| 	npiv_fabric = target_fabric_configfs_init(THIS_MODULE, "qla2xxx_npiv"); | ||||
| 	if (IS_ERR(npiv_fabric)) { | ||||
| 		pr_err("target_fabric_configfs_init() failed\n"); | ||||
| 		ret = PTR_ERR(npiv_fabric); | ||||
| 	ret = target_register_template(&tcm_qla2xxx_ops); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	ret = target_register_template(&tcm_qla2xxx_npiv_ops); | ||||
| 	if (ret) | ||||
| 		goto out_fabric; | ||||
| 	} | ||||
| 	/*
 | ||||
| 	 * Setup fabric->tf_ops from our local tcm_qla2xxx_npiv_ops | ||||
| 	 */ | ||||
| 	npiv_fabric->tf_ops = tcm_qla2xxx_npiv_ops; | ||||
| 	/*
 | ||||
| 	 * Setup default attribute lists for various npiv_fabric->tf_cit_tmpl | ||||
| 	 */ | ||||
| 	npiv_fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = tcm_qla2xxx_wwn_attrs; | ||||
| 	npiv_fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = | ||||
| 	    tcm_qla2xxx_npiv_tpg_attrs; | ||||
| 	npiv_fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = NULL; | ||||
| 	npiv_fabric->tf_cit_tmpl.tfc_tpg_param_cit.ct_attrs = NULL; | ||||
| 	npiv_fabric->tf_cit_tmpl.tfc_tpg_np_base_cit.ct_attrs = NULL; | ||||
| 	npiv_fabric->tf_cit_tmpl.tfc_tpg_nacl_base_cit.ct_attrs = NULL; | ||||
| 	npiv_fabric->tf_cit_tmpl.tfc_tpg_nacl_attrib_cit.ct_attrs = NULL; | ||||
| 	npiv_fabric->tf_cit_tmpl.tfc_tpg_nacl_auth_cit.ct_attrs = NULL; | ||||
| 	npiv_fabric->tf_cit_tmpl.tfc_tpg_nacl_param_cit.ct_attrs = NULL; | ||||
| 	/*
 | ||||
| 	 * Register the npiv_fabric for use within TCM | ||||
| 	 */ | ||||
| 	ret = target_fabric_configfs_register(npiv_fabric); | ||||
| 	if (ret < 0) { | ||||
| 		pr_err("target_fabric_configfs_register() failed for TCM_QLA2XXX\n"); | ||||
| 		goto out_fabric; | ||||
| 	} | ||||
| 	/*
 | ||||
| 	 * Setup our local pointer to *npiv_fabric | ||||
| 	 */ | ||||
| 	tcm_qla2xxx_npiv_fabric_configfs = npiv_fabric; | ||||
| 	pr_debug("TCM_QLA2XXX[0] - Set fabric -> tcm_qla2xxx_npiv_fabric_configfs\n"); | ||||
| 
 | ||||
| 	tcm_qla2xxx_free_wq = alloc_workqueue("tcm_qla2xxx_free", | ||||
| 						WQ_MEM_RECLAIM, 0); | ||||
| @ -2194,9 +2133,9 @@ static int tcm_qla2xxx_register_configfs(void) | ||||
| out_free_wq: | ||||
| 	destroy_workqueue(tcm_qla2xxx_free_wq); | ||||
| out_fabric_npiv: | ||||
| 	target_fabric_configfs_deregister(tcm_qla2xxx_npiv_fabric_configfs); | ||||
| 	target_unregister_template(&tcm_qla2xxx_npiv_ops); | ||||
| out_fabric: | ||||
| 	target_fabric_configfs_deregister(tcm_qla2xxx_fabric_configfs); | ||||
| 	target_unregister_template(&tcm_qla2xxx_ops); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| @ -2205,13 +2144,8 @@ static void tcm_qla2xxx_deregister_configfs(void) | ||||
| 	destroy_workqueue(tcm_qla2xxx_cmd_wq); | ||||
| 	destroy_workqueue(tcm_qla2xxx_free_wq); | ||||
| 
 | ||||
| 	target_fabric_configfs_deregister(tcm_qla2xxx_fabric_configfs); | ||||
| 	tcm_qla2xxx_fabric_configfs = NULL; | ||||
| 	pr_debug("TCM_QLA2XXX[0] - Cleared tcm_qla2xxx_fabric_configfs\n"); | ||||
| 
 | ||||
| 	target_fabric_configfs_deregister(tcm_qla2xxx_npiv_fabric_configfs); | ||||
| 	tcm_qla2xxx_npiv_fabric_configfs = NULL; | ||||
| 	pr_debug("TCM_QLA2XXX[0] - Cleared tcm_qla2xxx_npiv_fabric_configfs\n"); | ||||
| 	target_unregister_template(&tcm_qla2xxx_ops); | ||||
| 	target_unregister_template(&tcm_qla2xxx_npiv_ops); | ||||
| } | ||||
| 
 | ||||
| static int __init tcm_qla2xxx_init(void) | ||||
|  | ||||
| @ -33,7 +33,6 @@ | ||||
| #include <target/iscsi/iscsi_target_core.h> | ||||
| #include "iscsi_target_parameters.h" | ||||
| #include "iscsi_target_seq_pdu_list.h" | ||||
| #include "iscsi_target_configfs.h" | ||||
| #include "iscsi_target_datain_values.h" | ||||
| #include "iscsi_target_erl0.h" | ||||
| #include "iscsi_target_erl1.h" | ||||
| @ -551,8 +550,8 @@ static int __init iscsi_target_init_module(void) | ||||
| 	idr_init(&tiqn_idr); | ||||
| 	idr_init(&sess_idr); | ||||
| 
 | ||||
| 	ret = iscsi_target_register_configfs(); | ||||
| 	if (ret < 0) | ||||
| 	ret = target_register_template(&iscsi_ops); | ||||
| 	if (ret) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	size = BITS_TO_LONGS(ISCSIT_BITMAP_BITS) * sizeof(long); | ||||
| @ -616,7 +615,10 @@ qr_out: | ||||
| bitmap_out: | ||||
| 	vfree(iscsit_global->ts_bitmap); | ||||
| configfs_out: | ||||
| 	iscsi_target_deregister_configfs(); | ||||
| 	/* XXX: this probably wants it to be it's own unwind step.. */ | ||||
| 	if (iscsit_global->discovery_tpg) | ||||
| 		iscsit_tpg_disable_portal_group(iscsit_global->discovery_tpg, 1); | ||||
| 	target_unregister_template(&iscsi_ops); | ||||
| out: | ||||
| 	kfree(iscsit_global); | ||||
| 	return -ENOMEM; | ||||
| @ -631,7 +633,13 @@ static void __exit iscsi_target_cleanup_module(void) | ||||
| 	kmem_cache_destroy(lio_ooo_cache); | ||||
| 	kmem_cache_destroy(lio_r2t_cache); | ||||
| 
 | ||||
| 	iscsi_target_deregister_configfs(); | ||||
| 	/*
 | ||||
| 	 * Shutdown discovery sessions and disable discovery TPG | ||||
| 	 */ | ||||
| 	if (iscsit_global->discovery_tpg) | ||||
| 		iscsit_tpg_disable_portal_group(iscsit_global->discovery_tpg, 1); | ||||
| 
 | ||||
| 	target_unregister_template(&iscsi_ops); | ||||
| 
 | ||||
| 	vfree(iscsit_global->ts_bitmap); | ||||
| 	kfree(iscsit_global); | ||||
| @ -983,7 +991,7 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | ||||
| 	/*
 | ||||
| 	 * Initialize struct se_cmd descriptor from target_core_mod infrastructure | ||||
| 	 */ | ||||
| 	transport_init_se_cmd(&cmd->se_cmd, &lio_target_fabric_configfs->tf_ops, | ||||
| 	transport_init_se_cmd(&cmd->se_cmd, &iscsi_ops, | ||||
| 			conn->sess->se_sess, be32_to_cpu(hdr->data_length), | ||||
| 			cmd->data_direction, sam_task_attr, | ||||
| 			cmd->sense_buffer + 2); | ||||
| @ -1798,8 +1806,7 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | ||||
| 		u8 tcm_function; | ||||
| 		int ret; | ||||
| 
 | ||||
| 		transport_init_se_cmd(&cmd->se_cmd, | ||||
| 				      &lio_target_fabric_configfs->tf_ops, | ||||
| 		transport_init_se_cmd(&cmd->se_cmd, &iscsi_ops, | ||||
| 				      conn->sess->se_sess, 0, DMA_NONE, | ||||
| 				      TCM_SIMPLE_TAG, cmd->sense_buffer + 2); | ||||
| 
 | ||||
|  | ||||
| @ -35,7 +35,7 @@ extern void iscsit_stop_session(struct iscsi_session *, int, int); | ||||
| extern int iscsit_release_sessions_for_tpg(struct iscsi_portal_group *, int); | ||||
| 
 | ||||
| extern struct iscsit_global *iscsit_global; | ||||
| extern struct target_fabric_configfs *lio_target_fabric_configfs; | ||||
| extern const struct target_core_fabric_ops iscsi_ops; | ||||
| 
 | ||||
| extern struct kmem_cache *lio_dr_cache; | ||||
| extern struct kmem_cache *lio_ooo_cache; | ||||
|  | ||||
| @ -37,9 +37,6 @@ | ||||
| #include "iscsi_target_util.h" | ||||
| #include "iscsi_target.h" | ||||
| #include <target/iscsi/iscsi_target_stat.h> | ||||
| #include "iscsi_target_configfs.h" | ||||
| 
 | ||||
| struct target_fabric_configfs *lio_target_fabric_configfs; | ||||
| 
 | ||||
| struct lio_target_configfs_attribute { | ||||
| 	struct configfs_attribute attr; | ||||
| @ -1466,10 +1463,8 @@ static struct se_portal_group *lio_target_tiqn_addtpg( | ||||
| 	if (!tpg) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	ret = core_tpg_register( | ||||
| 			&lio_target_fabric_configfs->tf_ops, | ||||
| 			wwn, &tpg->tpg_se_tpg, tpg, | ||||
| 			TRANSPORT_TPG_TYPE_NORMAL); | ||||
| 	ret = core_tpg_register(&iscsi_ops, wwn, &tpg->tpg_se_tpg, | ||||
| 				tpg, TRANSPORT_TPG_TYPE_NORMAL); | ||||
| 	if (ret < 0) | ||||
| 		return NULL; | ||||
| 
 | ||||
| @ -1983,117 +1978,60 @@ static void lio_release_cmd(struct se_cmd *se_cmd) | ||||
| 	iscsit_release_cmd(cmd); | ||||
| } | ||||
| 
 | ||||
| /* End functions for target_core_fabric_ops */ | ||||
| const struct target_core_fabric_ops iscsi_ops = { | ||||
| 	.module				= THIS_MODULE, | ||||
| 	.name				= "iscsi", | ||||
| 	.get_fabric_name		= iscsi_get_fabric_name, | ||||
| 	.get_fabric_proto_ident		= iscsi_get_fabric_proto_ident, | ||||
| 	.tpg_get_wwn			= lio_tpg_get_endpoint_wwn, | ||||
| 	.tpg_get_tag			= lio_tpg_get_tag, | ||||
| 	.tpg_get_default_depth		= lio_tpg_get_default_depth, | ||||
| 	.tpg_get_pr_transport_id	= iscsi_get_pr_transport_id, | ||||
| 	.tpg_get_pr_transport_id_len	= iscsi_get_pr_transport_id_len, | ||||
| 	.tpg_parse_pr_out_transport_id	= iscsi_parse_pr_out_transport_id, | ||||
| 	.tpg_check_demo_mode		= lio_tpg_check_demo_mode, | ||||
| 	.tpg_check_demo_mode_cache	= lio_tpg_check_demo_mode_cache, | ||||
| 	.tpg_check_demo_mode_write_protect = | ||||
| 			lio_tpg_check_demo_mode_write_protect, | ||||
| 	.tpg_check_prod_mode_write_protect = | ||||
| 			lio_tpg_check_prod_mode_write_protect, | ||||
| 	.tpg_check_prot_fabric_only	= &lio_tpg_check_prot_fabric_only, | ||||
| 	.tpg_alloc_fabric_acl		= lio_tpg_alloc_fabric_acl, | ||||
| 	.tpg_release_fabric_acl		= lio_tpg_release_fabric_acl, | ||||
| 	.tpg_get_inst_index		= lio_tpg_get_inst_index, | ||||
| 	.check_stop_free		= lio_check_stop_free, | ||||
| 	.release_cmd			= lio_release_cmd, | ||||
| 	.shutdown_session		= lio_tpg_shutdown_session, | ||||
| 	.close_session			= lio_tpg_close_session, | ||||
| 	.sess_get_index			= lio_sess_get_index, | ||||
| 	.sess_get_initiator_sid		= lio_sess_get_initiator_sid, | ||||
| 	.write_pending			= lio_write_pending, | ||||
| 	.write_pending_status		= lio_write_pending_status, | ||||
| 	.set_default_node_attributes	= lio_set_default_node_attributes, | ||||
| 	.get_task_tag			= iscsi_get_task_tag, | ||||
| 	.get_cmd_state			= iscsi_get_cmd_state, | ||||
| 	.queue_data_in			= lio_queue_data_in, | ||||
| 	.queue_status			= lio_queue_status, | ||||
| 	.queue_tm_rsp			= lio_queue_tm_rsp, | ||||
| 	.aborted_task			= lio_aborted_task, | ||||
| 	.fabric_make_wwn		= lio_target_call_coreaddtiqn, | ||||
| 	.fabric_drop_wwn		= lio_target_call_coredeltiqn, | ||||
| 	.fabric_make_tpg		= lio_target_tiqn_addtpg, | ||||
| 	.fabric_drop_tpg		= lio_target_tiqn_deltpg, | ||||
| 	.fabric_make_np			= lio_target_call_addnptotpg, | ||||
| 	.fabric_drop_np			= lio_target_call_delnpfromtpg, | ||||
| 	.fabric_make_nodeacl		= lio_target_make_nodeacl, | ||||
| 	.fabric_drop_nodeacl		= lio_target_drop_nodeacl, | ||||
| 
 | ||||
| int iscsi_target_register_configfs(void) | ||||
| { | ||||
| 	struct target_fabric_configfs *fabric; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	lio_target_fabric_configfs = NULL; | ||||
| 	fabric = target_fabric_configfs_init(THIS_MODULE, "iscsi"); | ||||
| 	if (IS_ERR(fabric)) { | ||||
| 		pr_err("target_fabric_configfs_init() for" | ||||
| 				" LIO-Target failed!\n"); | ||||
| 		return PTR_ERR(fabric); | ||||
| 	} | ||||
| 	/*
 | ||||
| 	 * Setup the fabric API of function pointers used by target_core_mod.. | ||||
| 	 */ | ||||
| 	fabric->tf_ops.get_fabric_name = &iscsi_get_fabric_name; | ||||
| 	fabric->tf_ops.get_fabric_proto_ident = &iscsi_get_fabric_proto_ident; | ||||
| 	fabric->tf_ops.tpg_get_wwn = &lio_tpg_get_endpoint_wwn; | ||||
| 	fabric->tf_ops.tpg_get_tag = &lio_tpg_get_tag; | ||||
| 	fabric->tf_ops.tpg_get_default_depth = &lio_tpg_get_default_depth; | ||||
| 	fabric->tf_ops.tpg_get_pr_transport_id = &iscsi_get_pr_transport_id; | ||||
| 	fabric->tf_ops.tpg_get_pr_transport_id_len = | ||||
| 				&iscsi_get_pr_transport_id_len; | ||||
| 	fabric->tf_ops.tpg_parse_pr_out_transport_id = | ||||
| 				&iscsi_parse_pr_out_transport_id; | ||||
| 	fabric->tf_ops.tpg_check_demo_mode = &lio_tpg_check_demo_mode; | ||||
| 	fabric->tf_ops.tpg_check_demo_mode_cache = | ||||
| 				&lio_tpg_check_demo_mode_cache; | ||||
| 	fabric->tf_ops.tpg_check_demo_mode_write_protect = | ||||
| 				&lio_tpg_check_demo_mode_write_protect; | ||||
| 	fabric->tf_ops.tpg_check_prod_mode_write_protect = | ||||
| 				&lio_tpg_check_prod_mode_write_protect; | ||||
| 	fabric->tf_ops.tpg_check_prot_fabric_only = | ||||
| 				&lio_tpg_check_prot_fabric_only; | ||||
| 	fabric->tf_ops.tpg_alloc_fabric_acl = &lio_tpg_alloc_fabric_acl; | ||||
| 	fabric->tf_ops.tpg_release_fabric_acl = &lio_tpg_release_fabric_acl; | ||||
| 	fabric->tf_ops.tpg_get_inst_index = &lio_tpg_get_inst_index; | ||||
| 	fabric->tf_ops.check_stop_free = &lio_check_stop_free, | ||||
| 	fabric->tf_ops.release_cmd = &lio_release_cmd; | ||||
| 	fabric->tf_ops.shutdown_session = &lio_tpg_shutdown_session; | ||||
| 	fabric->tf_ops.close_session = &lio_tpg_close_session; | ||||
| 	fabric->tf_ops.sess_get_index = &lio_sess_get_index; | ||||
| 	fabric->tf_ops.sess_get_initiator_sid = &lio_sess_get_initiator_sid; | ||||
| 	fabric->tf_ops.write_pending = &lio_write_pending; | ||||
| 	fabric->tf_ops.write_pending_status = &lio_write_pending_status; | ||||
| 	fabric->tf_ops.set_default_node_attributes = | ||||
| 				&lio_set_default_node_attributes; | ||||
| 	fabric->tf_ops.get_task_tag = &iscsi_get_task_tag; | ||||
| 	fabric->tf_ops.get_cmd_state = &iscsi_get_cmd_state; | ||||
| 	fabric->tf_ops.queue_data_in = &lio_queue_data_in; | ||||
| 	fabric->tf_ops.queue_status = &lio_queue_status; | ||||
| 	fabric->tf_ops.queue_tm_rsp = &lio_queue_tm_rsp; | ||||
| 	fabric->tf_ops.aborted_task = &lio_aborted_task; | ||||
| 	/*
 | ||||
| 	 * Setup function pointers for generic logic in target_core_fabric_configfs.c | ||||
| 	 */ | ||||
| 	fabric->tf_ops.fabric_make_wwn = &lio_target_call_coreaddtiqn; | ||||
| 	fabric->tf_ops.fabric_drop_wwn = &lio_target_call_coredeltiqn; | ||||
| 	fabric->tf_ops.fabric_make_tpg = &lio_target_tiqn_addtpg; | ||||
| 	fabric->tf_ops.fabric_drop_tpg = &lio_target_tiqn_deltpg; | ||||
| 	fabric->tf_ops.fabric_post_link	= NULL; | ||||
| 	fabric->tf_ops.fabric_pre_unlink = NULL; | ||||
| 	fabric->tf_ops.fabric_make_np = &lio_target_call_addnptotpg; | ||||
| 	fabric->tf_ops.fabric_drop_np = &lio_target_call_delnpfromtpg; | ||||
| 	fabric->tf_ops.fabric_make_nodeacl = &lio_target_make_nodeacl; | ||||
| 	fabric->tf_ops.fabric_drop_nodeacl = &lio_target_drop_nodeacl; | ||||
| 	/*
 | ||||
| 	 * Setup default attribute lists for various fabric->tf_cit_tmpl | ||||
| 	 * sturct config_item_type's | ||||
| 	 */ | ||||
| 	fabric->tf_cit_tmpl.tfc_discovery_cit.ct_attrs = lio_target_discovery_auth_attrs; | ||||
| 	fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = lio_target_wwn_attrs; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = lio_target_tpg_attrs; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = lio_target_tpg_attrib_attrs; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_auth_cit.ct_attrs = lio_target_tpg_auth_attrs; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_param_cit.ct_attrs = lio_target_tpg_param_attrs; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_np_base_cit.ct_attrs = lio_target_portal_attrs; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_base_cit.ct_attrs = lio_target_initiator_attrs; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_attrib_cit.ct_attrs = lio_target_nacl_attrib_attrs; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_auth_cit.ct_attrs = lio_target_nacl_auth_attrs; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_param_cit.ct_attrs = lio_target_nacl_param_attrs; | ||||
| 
 | ||||
| 	ret = target_fabric_configfs_register(fabric); | ||||
| 	if (ret < 0) { | ||||
| 		pr_err("target_fabric_configfs_register() for" | ||||
| 				" LIO-Target failed!\n"); | ||||
| 		target_fabric_configfs_free(fabric); | ||||
| 		return ret; | ||||
| 	} | ||||
| 
 | ||||
| 	lio_target_fabric_configfs = fabric; | ||||
| 	pr_debug("LIO_TARGET[0] - Set fabric ->" | ||||
| 			" lio_target_fabric_configfs\n"); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void iscsi_target_deregister_configfs(void) | ||||
| { | ||||
| 	if (!lio_target_fabric_configfs) | ||||
| 		return; | ||||
| 	/*
 | ||||
| 	 * Shutdown discovery sessions and disable discovery TPG | ||||
| 	 */ | ||||
| 	if (iscsit_global->discovery_tpg) | ||||
| 		iscsit_tpg_disable_portal_group(iscsit_global->discovery_tpg, 1); | ||||
| 
 | ||||
| 	target_fabric_configfs_deregister(lio_target_fabric_configfs); | ||||
| 	lio_target_fabric_configfs = NULL; | ||||
| 	pr_debug("LIO_TARGET[0] - Cleared" | ||||
| 				" lio_target_fabric_configfs\n"); | ||||
| } | ||||
| 	.tfc_discovery_attrs		= lio_target_discovery_auth_attrs, | ||||
| 	.tfc_wwn_attrs			= lio_target_wwn_attrs, | ||||
| 	.tfc_tpg_base_attrs		= lio_target_tpg_attrs, | ||||
| 	.tfc_tpg_attrib_attrs		= lio_target_tpg_attrib_attrs, | ||||
| 	.tfc_tpg_auth_attrs		= lio_target_tpg_auth_attrs, | ||||
| 	.tfc_tpg_param_attrs		= lio_target_tpg_param_attrs, | ||||
| 	.tfc_tpg_np_base_attrs		= lio_target_portal_attrs, | ||||
| 	.tfc_tpg_nacl_base_attrs	= lio_target_initiator_attrs, | ||||
| 	.tfc_tpg_nacl_attrib_attrs	= lio_target_nacl_attrib_attrs, | ||||
| 	.tfc_tpg_nacl_auth_attrs	= lio_target_nacl_auth_attrs, | ||||
| 	.tfc_tpg_nacl_param_attrs	= lio_target_nacl_param_attrs, | ||||
| }; | ||||
|  | ||||
| @ -1,7 +0,0 @@ | ||||
| #ifndef ISCSI_TARGET_CONFIGFS_H | ||||
| #define ISCSI_TARGET_CONFIGFS_H | ||||
| 
 | ||||
| extern int iscsi_target_register_configfs(void); | ||||
| extern void iscsi_target_deregister_configfs(void); | ||||
| 
 | ||||
| #endif /* ISCSI_TARGET_CONFIGFS_H */ | ||||
| @ -68,10 +68,8 @@ int iscsit_load_discovery_tpg(void) | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	ret = core_tpg_register( | ||||
| 			&lio_target_fabric_configfs->tf_ops, | ||||
| 			NULL, &tpg->tpg_se_tpg, tpg, | ||||
| 			TRANSPORT_TPG_TYPE_DISCOVERY); | ||||
| 	ret = core_tpg_register(&iscsi_ops, NULL, &tpg->tpg_se_tpg, | ||||
| 				tpg, TRANSPORT_TPG_TYPE_DISCOVERY); | ||||
| 	if (ret < 0) { | ||||
| 		kfree(tpg); | ||||
| 		return -1; | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -42,8 +42,7 @@ | ||||
| 
 | ||||
| #include "sbp_target.h" | ||||
| 
 | ||||
| /* Local pointer to allocated TCM configfs fabric module */ | ||||
| static struct target_fabric_configfs *sbp_fabric_configfs; | ||||
| static const struct target_core_fabric_ops sbp_ops; | ||||
| 
 | ||||
| /* FireWire address region for management and command block address handlers */ | ||||
| static const struct fw_address_region sbp_register_region = { | ||||
| @ -2215,8 +2214,7 @@ static struct se_portal_group *sbp_make_tpg( | ||||
| 		goto out_free_tpg; | ||||
| 	} | ||||
| 
 | ||||
| 	ret = core_tpg_register(&sbp_fabric_configfs->tf_ops, wwn, | ||||
| 			&tpg->se_tpg, (void *)tpg, | ||||
| 	ret = core_tpg_register(&sbp_ops, wwn, &tpg->se_tpg, tpg, | ||||
| 			TRANSPORT_TPG_TYPE_NORMAL); | ||||
| 	if (ret < 0) | ||||
| 		goto out_unreg_mgt_agt; | ||||
| @ -2503,7 +2501,9 @@ static struct configfs_attribute *sbp_tpg_attrib_attrs[] = { | ||||
| 	NULL, | ||||
| }; | ||||
| 
 | ||||
| static struct target_core_fabric_ops sbp_ops = { | ||||
| static const struct target_core_fabric_ops sbp_ops = { | ||||
| 	.module				= THIS_MODULE, | ||||
| 	.name				= "sbp", | ||||
| 	.get_fabric_name		= sbp_get_fabric_name, | ||||
| 	.get_fabric_proto_ident		= sbp_get_fabric_proto_ident, | ||||
| 	.tpg_get_wwn			= sbp_get_fabric_wwn, | ||||
| @ -2544,68 +2544,20 @@ static struct target_core_fabric_ops sbp_ops = { | ||||
| 	.fabric_drop_np			= NULL, | ||||
| 	.fabric_make_nodeacl		= sbp_make_nodeacl, | ||||
| 	.fabric_drop_nodeacl		= sbp_drop_nodeacl, | ||||
| }; | ||||
| 
 | ||||
| static int sbp_register_configfs(void) | ||||
| { | ||||
| 	struct target_fabric_configfs *fabric; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	fabric = target_fabric_configfs_init(THIS_MODULE, "sbp"); | ||||
| 	if (IS_ERR(fabric)) { | ||||
| 		pr_err("target_fabric_configfs_init() failed\n"); | ||||
| 		return PTR_ERR(fabric); | ||||
| 	} | ||||
| 
 | ||||
| 	fabric->tf_ops = sbp_ops; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Setup default attribute lists for various fabric->tf_cit_tmpl | ||||
| 	 */ | ||||
| 	fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = sbp_wwn_attrs; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = sbp_tpg_base_attrs; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = sbp_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; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_base_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_attrib_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_auth_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_param_cit.ct_attrs = NULL; | ||||
| 
 | ||||
| 	ret = target_fabric_configfs_register(fabric); | ||||
| 	if (ret < 0) { | ||||
| 		pr_err("target_fabric_configfs_register() failed for SBP\n"); | ||||
| 		return ret; | ||||
| 	} | ||||
| 
 | ||||
| 	sbp_fabric_configfs = fabric; | ||||
| 
 | ||||
| 	return 0; | ||||
| }; | ||||
| 
 | ||||
| static void sbp_deregister_configfs(void) | ||||
| { | ||||
| 	if (!sbp_fabric_configfs) | ||||
| 		return; | ||||
| 
 | ||||
| 	target_fabric_configfs_deregister(sbp_fabric_configfs); | ||||
| 	sbp_fabric_configfs = NULL; | ||||
| 	.tfc_wwn_attrs			= sbp_wwn_attrs, | ||||
| 	.tfc_tpg_base_attrs		= sbp_tpg_base_attrs, | ||||
| 	.tfc_tpg_attrib_attrs		= sbp_tpg_attrib_attrs, | ||||
| }; | ||||
| 
 | ||||
| static int __init sbp_init(void) | ||||
| { | ||||
| 	int ret; | ||||
| 
 | ||||
| 	ret = sbp_register_configfs(); | ||||
| 	if (ret < 0) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	return 0; | ||||
| 	return target_register_template(&sbp_ops); | ||||
| }; | ||||
| 
 | ||||
| static void __exit sbp_exit(void) | ||||
| { | ||||
| 	sbp_deregister_configfs(); | ||||
| 	target_unregister_template(&sbp_ops); | ||||
| }; | ||||
| 
 | ||||
| MODULE_DESCRIPTION("FireWire SBP fabric driver"); | ||||
|  | ||||
| @ -300,81 +300,17 @@ struct configfs_subsystem *target_core_subsystem[] = { | ||||
| // Start functions called by external Target Fabrics Modules
 | ||||
| //############################################################################*/
 | ||||
| 
 | ||||
| /*
 | ||||
|  * First function called by fabric modules to: | ||||
|  * | ||||
|  * 1) Allocate a struct target_fabric_configfs and save the *fabric_cit pointer. | ||||
|  * 2) Add struct target_fabric_configfs to g_tf_list | ||||
|  * 3) Return struct target_fabric_configfs to fabric module to be passed | ||||
|  *    into target_fabric_configfs_register(). | ||||
|  */ | ||||
| struct target_fabric_configfs *target_fabric_configfs_init( | ||||
| 	struct module *fabric_mod, | ||||
| 	const char *name) | ||||
| static int target_fabric_tf_ops_check(const struct target_core_fabric_ops *tfo) | ||||
| { | ||||
| 	struct target_fabric_configfs *tf; | ||||
| 
 | ||||
| 	if (!(name)) { | ||||
| 		pr_err("Unable to locate passed fabric name\n"); | ||||
| 		return ERR_PTR(-EINVAL); | ||||
| 	if (!tfo->name) { | ||||
| 		pr_err("Missing tfo->name\n"); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 	if (strlen(name) >= TARGET_FABRIC_NAME_SIZE) { | ||||
| 	if (strlen(tfo->name) >= TARGET_FABRIC_NAME_SIZE) { | ||||
| 		pr_err("Passed name: %s exceeds TARGET_FABRIC" | ||||
| 			"_NAME_SIZE\n", name); | ||||
| 		return ERR_PTR(-EINVAL); | ||||
| 			"_NAME_SIZE\n", tfo->name); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
| 	tf = kzalloc(sizeof(struct target_fabric_configfs), GFP_KERNEL); | ||||
| 	if (!tf) | ||||
| 		return ERR_PTR(-ENOMEM); | ||||
| 
 | ||||
| 	INIT_LIST_HEAD(&tf->tf_list); | ||||
| 	atomic_set(&tf->tf_access_cnt, 0); | ||||
| 	/*
 | ||||
| 	 * Setup the default generic struct config_item_type's (cits) in | ||||
| 	 * struct target_fabric_configfs->tf_cit_tmpl | ||||
| 	 */ | ||||
| 	tf->tf_module = fabric_mod; | ||||
| 	target_fabric_setup_cits(tf); | ||||
| 
 | ||||
| 	tf->tf_subsys = target_core_subsystem[0]; | ||||
| 	snprintf(tf->tf_name, TARGET_FABRIC_NAME_SIZE, "%s", name); | ||||
| 
 | ||||
| 	mutex_lock(&g_tf_lock); | ||||
| 	list_add_tail(&tf->tf_list, &g_tf_list); | ||||
| 	mutex_unlock(&g_tf_lock); | ||||
| 
 | ||||
| 	pr_debug("<<<<<<<<<<<<<<<<<<<<<< BEGIN FABRIC API >>>>>>>>" | ||||
| 			">>>>>>>>>>>>>>\n"); | ||||
| 	pr_debug("Initialized struct target_fabric_configfs: %p for" | ||||
| 			" %s\n", tf, tf->tf_name); | ||||
| 	return tf; | ||||
| } | ||||
| EXPORT_SYMBOL(target_fabric_configfs_init); | ||||
| 
 | ||||
| /*
 | ||||
|  * Called by fabric plugins after FAILED target_fabric_configfs_register() call. | ||||
|  */ | ||||
| void target_fabric_configfs_free( | ||||
| 	struct target_fabric_configfs *tf) | ||||
| { | ||||
| 	mutex_lock(&g_tf_lock); | ||||
| 	list_del(&tf->tf_list); | ||||
| 	mutex_unlock(&g_tf_lock); | ||||
| 
 | ||||
| 	kfree(tf); | ||||
| } | ||||
| EXPORT_SYMBOL(target_fabric_configfs_free); | ||||
| 
 | ||||
| /*
 | ||||
|  * Perform a sanity check of the passed tf->tf_ops before completing | ||||
|  * TCM fabric module registration. | ||||
|  */ | ||||
| static int target_fabric_tf_ops_check( | ||||
| 	struct target_fabric_configfs *tf) | ||||
| { | ||||
| 	struct target_core_fabric_ops *tfo = &tf->tf_ops; | ||||
| 
 | ||||
| 	if (!tfo->get_fabric_name) { | ||||
| 		pr_err("Missing tfo->get_fabric_name()\n"); | ||||
| 		return -EINVAL; | ||||
| @ -508,77 +444,59 @@ static int target_fabric_tf_ops_check( | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Called 2nd from fabric module with returned parameter of | ||||
|  * struct target_fabric_configfs * from target_fabric_configfs_init(). | ||||
|  * | ||||
|  * Upon a successful registration, the new fabric's struct config_item is | ||||
|  * return.  Also, a pointer to this struct is set in the passed | ||||
|  * struct target_fabric_configfs. | ||||
|  */ | ||||
| int target_fabric_configfs_register( | ||||
| 	struct target_fabric_configfs *tf) | ||||
| int target_register_template(const struct target_core_fabric_ops *fo) | ||||
| { | ||||
| 	struct target_fabric_configfs *tf; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	if (!tf) { | ||||
| 		pr_err("Unable to locate target_fabric_configfs" | ||||
| 			" pointer\n"); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 	if (!tf->tf_subsys) { | ||||
| 		pr_err("Unable to target struct config_subsystem" | ||||
| 			" pointer\n"); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 	ret = target_fabric_tf_ops_check(tf); | ||||
| 	if (ret < 0) | ||||
| 	ret = target_fabric_tf_ops_check(fo); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	pr_debug("<<<<<<<<<<<<<<<<<<<<<< END FABRIC API >>>>>>>>>>>>" | ||||
| 		">>>>>>>>>>\n"); | ||||
| 	return 0; | ||||
| } | ||||
| EXPORT_SYMBOL(target_fabric_configfs_register); | ||||
| 
 | ||||
| void target_fabric_configfs_deregister( | ||||
| 	struct target_fabric_configfs *tf) | ||||
| { | ||||
| 	struct configfs_subsystem *su; | ||||
| 
 | ||||
| 	tf = kzalloc(sizeof(struct target_fabric_configfs), GFP_KERNEL); | ||||
| 	if (!tf) { | ||||
| 		pr_err("Unable to locate passed target_fabric_" | ||||
| 			"configfs\n"); | ||||
| 		return; | ||||
| 		pr_err("%s: could not allocate memory!\n", __func__); | ||||
| 		return -ENOMEM; | ||||
| 	} | ||||
| 	su = tf->tf_subsys; | ||||
| 	if (!su) { | ||||
| 		pr_err("Unable to locate passed tf->tf_subsys" | ||||
| 			" pointer\n"); | ||||
| 		return; | ||||
| 	} | ||||
| 	pr_debug("<<<<<<<<<<<<<<<<<<<<<< BEGIN FABRIC API >>>>>>>>>>" | ||||
| 			">>>>>>>>>>>>\n"); | ||||
| 
 | ||||
| 	INIT_LIST_HEAD(&tf->tf_list); | ||||
| 	atomic_set(&tf->tf_access_cnt, 0); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Setup the default generic struct config_item_type's (cits) in | ||||
| 	 * struct target_fabric_configfs->tf_cit_tmpl | ||||
| 	 */ | ||||
| 	tf->tf_module = fo->module; | ||||
| 	tf->tf_subsys = target_core_subsystem[0]; | ||||
| 	snprintf(tf->tf_name, TARGET_FABRIC_NAME_SIZE, "%s", fo->name); | ||||
| 
 | ||||
| 	tf->tf_ops = *fo; | ||||
| 	target_fabric_setup_cits(tf); | ||||
| 
 | ||||
| 	mutex_lock(&g_tf_lock); | ||||
| 	if (atomic_read(&tf->tf_access_cnt)) { | ||||
| 		mutex_unlock(&g_tf_lock); | ||||
| 		pr_err("Non zero tf->tf_access_cnt for fabric %s\n", | ||||
| 			tf->tf_name); | ||||
| 		BUG(); | ||||
| 	} | ||||
| 	list_del(&tf->tf_list); | ||||
| 	list_add_tail(&tf->tf_list, &g_tf_list); | ||||
| 	mutex_unlock(&g_tf_lock); | ||||
| 
 | ||||
| 	pr_debug("Target_Core_ConfigFS: DEREGISTER -> Releasing tf:" | ||||
| 			" %s\n", tf->tf_name); | ||||
| 	tf->tf_module = NULL; | ||||
| 	tf->tf_subsys = NULL; | ||||
| 	kfree(tf); | ||||
| 
 | ||||
| 	pr_debug("<<<<<<<<<<<<<<<<<<<<<< END FABRIC API >>>>>>>>>>>>>>>>>" | ||||
| 			">>>>>\n"); | ||||
| 	return 0; | ||||
| } | ||||
| EXPORT_SYMBOL(target_fabric_configfs_deregister); | ||||
| EXPORT_SYMBOL(target_register_template); | ||||
| 
 | ||||
| void target_unregister_template(const struct target_core_fabric_ops *fo) | ||||
| { | ||||
| 	struct target_fabric_configfs *t; | ||||
| 
 | ||||
| 	mutex_lock(&g_tf_lock); | ||||
| 	list_for_each_entry(t, &g_tf_list, tf_list) { | ||||
| 		if (!strcmp(t->tf_name, fo->name)) { | ||||
| 			BUG_ON(atomic_read(&t->tf_access_cnt)); | ||||
| 			list_del(&t->tf_list); | ||||
| 			kfree(t); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	mutex_unlock(&g_tf_lock); | ||||
| } | ||||
| EXPORT_SYMBOL(target_unregister_template); | ||||
| 
 | ||||
| /*##############################################################################
 | ||||
| // Stop functions called by external Target Fabrics Modules
 | ||||
| @ -945,7 +863,7 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_holder_tg_port( | ||||
| 	struct se_lun *lun; | ||||
| 	struct se_portal_group *se_tpg; | ||||
| 	struct t10_pr_registration *pr_reg; | ||||
| 	struct target_core_fabric_ops *tfo; | ||||
| 	const struct target_core_fabric_ops *tfo; | ||||
| 	ssize_t len = 0; | ||||
| 
 | ||||
| 	spin_lock(&dev->dev_reservation_lock); | ||||
| @ -979,7 +897,7 @@ SE_DEV_PR_ATTR_RO(res_pr_holder_tg_port); | ||||
| static ssize_t target_core_dev_pr_show_attr_res_pr_registered_i_pts( | ||||
| 		struct se_device *dev, char *page) | ||||
| { | ||||
| 	struct target_core_fabric_ops *tfo; | ||||
| 	const struct target_core_fabric_ops *tfo; | ||||
| 	struct t10_pr_registration *pr_reg; | ||||
| 	unsigned char buf[384]; | ||||
| 	char i_buf[PR_REG_ISID_ID_LEN]; | ||||
|  | ||||
| @ -56,6 +56,20 @@ static void target_fabric_setup_##_name##_cit(struct target_fabric_configfs *tf) | ||||
| 	pr_debug("Setup generic %s\n", __stringify(_name));		\ | ||||
| } | ||||
| 
 | ||||
| #define TF_CIT_SETUP_DRV(_name, _item_ops, _group_ops)		\ | ||||
| static void target_fabric_setup_##_name##_cit(struct target_fabric_configfs *tf) \ | ||||
| {									\ | ||||
| 	struct target_fabric_configfs_template *tfc = &tf->tf_cit_tmpl;	\ | ||||
| 	struct config_item_type *cit = &tfc->tfc_##_name##_cit;		\ | ||||
| 	struct configfs_attribute **attrs = tf->tf_ops.tfc_##_name##_attrs; \ | ||||
| 									\ | ||||
| 	cit->ct_item_ops = _item_ops;					\ | ||||
| 	cit->ct_group_ops = _group_ops;					\ | ||||
| 	cit->ct_attrs = attrs;						\ | ||||
| 	cit->ct_owner = tf->tf_module;					\ | ||||
| 	pr_debug("Setup generic %s\n", __stringify(_name));		\ | ||||
| } | ||||
| 
 | ||||
| /* Start of tfc_tpg_mappedlun_cit */ | ||||
| 
 | ||||
| static int target_fabric_mappedlun_link( | ||||
| @ -278,7 +292,7 @@ static struct configfs_item_operations target_fabric_nacl_attrib_item_ops = { | ||||
| 	.store_attribute	= target_fabric_nacl_attrib_attr_store, | ||||
| }; | ||||
| 
 | ||||
| TF_CIT_SETUP(tpg_nacl_attrib, &target_fabric_nacl_attrib_item_ops, NULL, NULL); | ||||
| TF_CIT_SETUP_DRV(tpg_nacl_attrib, &target_fabric_nacl_attrib_item_ops, NULL); | ||||
| 
 | ||||
| /* End of tfc_tpg_nacl_attrib_cit */ | ||||
| 
 | ||||
| @ -291,7 +305,7 @@ static struct configfs_item_operations target_fabric_nacl_auth_item_ops = { | ||||
| 	.store_attribute	= target_fabric_nacl_auth_attr_store, | ||||
| }; | ||||
| 
 | ||||
| TF_CIT_SETUP(tpg_nacl_auth, &target_fabric_nacl_auth_item_ops, NULL, NULL); | ||||
| TF_CIT_SETUP_DRV(tpg_nacl_auth, &target_fabric_nacl_auth_item_ops, NULL); | ||||
| 
 | ||||
| /* End of tfc_tpg_nacl_auth_cit */ | ||||
| 
 | ||||
| @ -304,7 +318,7 @@ static struct configfs_item_operations target_fabric_nacl_param_item_ops = { | ||||
| 	.store_attribute	= target_fabric_nacl_param_attr_store, | ||||
| }; | ||||
| 
 | ||||
| TF_CIT_SETUP(tpg_nacl_param, &target_fabric_nacl_param_item_ops, NULL, NULL); | ||||
| TF_CIT_SETUP_DRV(tpg_nacl_param, &target_fabric_nacl_param_item_ops, NULL); | ||||
| 
 | ||||
| /* End of tfc_tpg_nacl_param_cit */ | ||||
| 
 | ||||
| @ -461,8 +475,8 @@ static struct configfs_group_operations target_fabric_nacl_base_group_ops = { | ||||
| 	.drop_item		= target_fabric_drop_mappedlun, | ||||
| }; | ||||
| 
 | ||||
| TF_CIT_SETUP(tpg_nacl_base, &target_fabric_nacl_base_item_ops, | ||||
| 		&target_fabric_nacl_base_group_ops, NULL); | ||||
| TF_CIT_SETUP_DRV(tpg_nacl_base, &target_fabric_nacl_base_item_ops, | ||||
| 		&target_fabric_nacl_base_group_ops); | ||||
| 
 | ||||
| /* End of tfc_tpg_nacl_base_cit */ | ||||
| 
 | ||||
| @ -570,7 +584,7 @@ static struct configfs_item_operations target_fabric_np_base_item_ops = { | ||||
| 	.store_attribute	= target_fabric_np_base_attr_store, | ||||
| }; | ||||
| 
 | ||||
| TF_CIT_SETUP(tpg_np_base, &target_fabric_np_base_item_ops, NULL, NULL); | ||||
| TF_CIT_SETUP_DRV(tpg_np_base, &target_fabric_np_base_item_ops, NULL); | ||||
| 
 | ||||
| /* End of tfc_tpg_np_base_cit */ | ||||
| 
 | ||||
| @ -966,7 +980,7 @@ static struct configfs_item_operations target_fabric_tpg_attrib_item_ops = { | ||||
| 	.store_attribute	= target_fabric_tpg_attrib_attr_store, | ||||
| }; | ||||
| 
 | ||||
| TF_CIT_SETUP(tpg_attrib, &target_fabric_tpg_attrib_item_ops, NULL, NULL); | ||||
| TF_CIT_SETUP_DRV(tpg_attrib, &target_fabric_tpg_attrib_item_ops, NULL); | ||||
| 
 | ||||
| /* End of tfc_tpg_attrib_cit */ | ||||
| 
 | ||||
| @ -979,7 +993,7 @@ static struct configfs_item_operations target_fabric_tpg_auth_item_ops = { | ||||
| 	.store_attribute	= target_fabric_tpg_auth_attr_store, | ||||
| }; | ||||
| 
 | ||||
| TF_CIT_SETUP(tpg_auth, &target_fabric_tpg_auth_item_ops, NULL, NULL); | ||||
| TF_CIT_SETUP_DRV(tpg_auth, &target_fabric_tpg_auth_item_ops, NULL); | ||||
| 
 | ||||
| /* End of tfc_tpg_attrib_cit */ | ||||
| 
 | ||||
| @ -992,7 +1006,7 @@ static struct configfs_item_operations target_fabric_tpg_param_item_ops = { | ||||
| 	.store_attribute	= target_fabric_tpg_param_attr_store, | ||||
| }; | ||||
| 
 | ||||
| TF_CIT_SETUP(tpg_param, &target_fabric_tpg_param_item_ops, NULL, NULL); | ||||
| TF_CIT_SETUP_DRV(tpg_param, &target_fabric_tpg_param_item_ops, NULL); | ||||
| 
 | ||||
| /* End of tfc_tpg_param_cit */ | ||||
| 
 | ||||
| @ -1018,7 +1032,7 @@ static struct configfs_item_operations target_fabric_tpg_base_item_ops = { | ||||
| 	.store_attribute	= target_fabric_tpg_attr_store, | ||||
| }; | ||||
| 
 | ||||
| TF_CIT_SETUP(tpg_base, &target_fabric_tpg_base_item_ops, NULL, NULL); | ||||
| TF_CIT_SETUP_DRV(tpg_base, &target_fabric_tpg_base_item_ops, NULL); | ||||
| 
 | ||||
| /* End of tfc_tpg_base_cit */ | ||||
| 
 | ||||
| @ -1192,7 +1206,7 @@ static struct configfs_item_operations target_fabric_wwn_item_ops = { | ||||
| 	.store_attribute	= target_fabric_wwn_attr_store, | ||||
| }; | ||||
| 
 | ||||
| TF_CIT_SETUP(wwn, &target_fabric_wwn_item_ops, &target_fabric_wwn_group_ops, NULL); | ||||
| TF_CIT_SETUP_DRV(wwn, &target_fabric_wwn_item_ops, &target_fabric_wwn_group_ops); | ||||
| 
 | ||||
| /* End of tfc_wwn_cit */ | ||||
| 
 | ||||
| @ -1206,7 +1220,7 @@ static struct configfs_item_operations target_fabric_discovery_item_ops = { | ||||
| 	.store_attribute	= target_fabric_discovery_attr_store, | ||||
| }; | ||||
| 
 | ||||
| TF_CIT_SETUP(discovery, &target_fabric_discovery_item_ops, NULL, NULL); | ||||
| TF_CIT_SETUP_DRV(discovery, &target_fabric_discovery_item_ops, NULL); | ||||
| 
 | ||||
| /* End of tfc_discovery_cit */ | ||||
| 
 | ||||
|  | ||||
| @ -680,7 +680,7 @@ static struct t10_pr_registration *__core_scsi3_alloc_registration( | ||||
| 	struct se_dev_entry *deve_tmp; | ||||
| 	struct se_node_acl *nacl_tmp; | ||||
| 	struct se_port *port, *port_tmp; | ||||
| 	struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo; | ||||
| 	const struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo; | ||||
| 	struct t10_pr_registration *pr_reg, *pr_reg_atp, *pr_reg_tmp, *pr_reg_tmp_safe; | ||||
| 	int ret; | ||||
| 	/*
 | ||||
| @ -979,7 +979,7 @@ int core_scsi3_check_aptpl_registration( | ||||
| } | ||||
| 
 | ||||
| static void __core_scsi3_dump_registration( | ||||
| 	struct target_core_fabric_ops *tfo, | ||||
| 	const struct target_core_fabric_ops *tfo, | ||||
| 	struct se_device *dev, | ||||
| 	struct se_node_acl *nacl, | ||||
| 	struct t10_pr_registration *pr_reg, | ||||
| @ -1020,7 +1020,7 @@ static void __core_scsi3_add_registration( | ||||
| 	enum register_type register_type, | ||||
| 	int register_move) | ||||
| { | ||||
| 	struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo; | ||||
| 	const struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo; | ||||
| 	struct t10_pr_registration *pr_reg_tmp, *pr_reg_tmp_safe; | ||||
| 	struct t10_reservation *pr_tmpl = &dev->t10_pr; | ||||
| 
 | ||||
| @ -1237,7 +1237,7 @@ static void __core_scsi3_free_registration( | ||||
| 	struct list_head *preempt_and_abort_list, | ||||
| 	int dec_holders) | ||||
| { | ||||
| 	struct target_core_fabric_ops *tfo = | ||||
| 	const struct target_core_fabric_ops *tfo = | ||||
| 			pr_reg->pr_reg_nacl->se_tpg->se_tpg_tfo; | ||||
| 	struct t10_reservation *pr_tmpl = &dev->t10_pr; | ||||
| 	char i_buf[PR_REG_ISID_ID_LEN]; | ||||
| @ -1461,7 +1461,7 @@ core_scsi3_decode_spec_i_port( | ||||
| 	struct t10_pr_registration *pr_reg_tmp, *pr_reg_tmp_safe; | ||||
| 	LIST_HEAD(tid_dest_list); | ||||
| 	struct pr_transport_id_holder *tidh_new, *tidh, *tidh_tmp; | ||||
| 	struct target_core_fabric_ops *tmp_tf_ops; | ||||
| 	const struct target_core_fabric_ops *tmp_tf_ops; | ||||
| 	unsigned char *buf; | ||||
| 	unsigned char *ptr, *i_str = NULL, proto_ident, tmp_proto_ident; | ||||
| 	char *iport_ptr = NULL, i_buf[PR_REG_ISID_ID_LEN]; | ||||
| @ -2422,7 +2422,7 @@ static void __core_scsi3_complete_pro_release( | ||||
| 	int explicit, | ||||
| 	int unreg) | ||||
| { | ||||
| 	struct target_core_fabric_ops *tfo = se_nacl->se_tpg->se_tpg_tfo; | ||||
| 	const struct target_core_fabric_ops *tfo = se_nacl->se_tpg->se_tpg_tfo; | ||||
| 	char i_buf[PR_REG_ISID_ID_LEN]; | ||||
| 	int pr_res_type = 0, pr_res_scope = 0; | ||||
| 
 | ||||
| @ -2734,7 +2734,7 @@ static void __core_scsi3_complete_pro_preempt( | ||||
| 	enum preempt_type preempt_type) | ||||
| { | ||||
| 	struct se_node_acl *nacl = pr_reg->pr_reg_nacl; | ||||
| 	struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo; | ||||
| 	const struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo; | ||||
| 	char i_buf[PR_REG_ISID_ID_LEN]; | ||||
| 
 | ||||
| 	memset(i_buf, 0, PR_REG_ISID_ID_LEN); | ||||
| @ -3119,7 +3119,7 @@ core_scsi3_emulate_pro_register_and_move(struct se_cmd *cmd, u64 res_key, | ||||
| 	struct se_node_acl *pr_res_nacl, *pr_reg_nacl, *dest_node_acl = NULL; | ||||
| 	struct se_port *se_port; | ||||
| 	struct se_portal_group *se_tpg, *dest_se_tpg = NULL; | ||||
| 	struct target_core_fabric_ops *dest_tf_ops = NULL, *tf_ops; | ||||
| 	const struct target_core_fabric_ops *dest_tf_ops = NULL, *tf_ops; | ||||
| 	struct t10_pr_registration *pr_reg, *pr_res_holder, *dest_pr_reg; | ||||
| 	struct t10_reservation *pr_tmpl = &dev->t10_pr; | ||||
| 	unsigned char *buf; | ||||
|  | ||||
| @ -672,7 +672,7 @@ static int core_tpg_setup_virtual_lun0(struct se_portal_group *se_tpg) | ||||
| } | ||||
| 
 | ||||
| int core_tpg_register( | ||||
| 	struct target_core_fabric_ops *tfo, | ||||
| 	const struct target_core_fabric_ops *tfo, | ||||
| 	struct se_wwn *se_wwn, | ||||
| 	struct se_portal_group *se_tpg, | ||||
| 	void *tpg_fabric_ptr, | ||||
|  | ||||
| @ -322,7 +322,7 @@ void __transport_register_session( | ||||
| 	struct se_session *se_sess, | ||||
| 	void *fabric_sess_ptr) | ||||
| { | ||||
| 	struct target_core_fabric_ops *tfo = se_tpg->se_tpg_tfo; | ||||
| 	const struct target_core_fabric_ops *tfo = se_tpg->se_tpg_tfo; | ||||
| 	unsigned char buf[PR_REG_ISID_LEN]; | ||||
| 
 | ||||
| 	se_sess->se_tpg = se_tpg; | ||||
| @ -494,7 +494,7 @@ EXPORT_SYMBOL(transport_free_session); | ||||
| void transport_deregister_session(struct se_session *se_sess) | ||||
| { | ||||
| 	struct se_portal_group *se_tpg = se_sess->se_tpg; | ||||
| 	struct target_core_fabric_ops *se_tfo; | ||||
| 	const struct target_core_fabric_ops *se_tfo; | ||||
| 	struct se_node_acl *se_nacl; | ||||
| 	unsigned long flags; | ||||
| 	bool comp_nacl = true; | ||||
| @ -1150,7 +1150,7 @@ target_cmd_size_check(struct se_cmd *cmd, unsigned int size) | ||||
|  */ | ||||
| void transport_init_se_cmd( | ||||
| 	struct se_cmd *cmd, | ||||
| 	struct target_core_fabric_ops *tfo, | ||||
| 	const struct target_core_fabric_ops *tfo, | ||||
| 	struct se_session *se_sess, | ||||
| 	u32 data_length, | ||||
| 	int data_direction, | ||||
|  | ||||
| @ -425,7 +425,7 @@ static int xcopy_pt_queue_status(struct se_cmd *se_cmd) | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static struct target_core_fabric_ops xcopy_pt_tfo = { | ||||
| static const struct target_core_fabric_ops xcopy_pt_tfo = { | ||||
| 	.get_fabric_name	= xcopy_pt_get_fabric_name, | ||||
| 	.get_task_tag		= xcopy_pt_get_tag, | ||||
| 	.get_cmd_state		= xcopy_pt_get_cmd_state, | ||||
|  | ||||
| @ -129,7 +129,6 @@ struct ft_cmd { | ||||
| 
 | ||||
| extern struct mutex ft_lport_lock; | ||||
| extern struct fc4_prov ft_prov; | ||||
| extern struct target_fabric_configfs *ft_configfs; | ||||
| extern unsigned int ft_debug_logging; | ||||
| 
 | ||||
| /*
 | ||||
|  | ||||
| @ -48,7 +48,7 @@ | ||||
| 
 | ||||
| #include "tcm_fc.h" | ||||
| 
 | ||||
| struct target_fabric_configfs *ft_configfs; | ||||
| static const struct target_core_fabric_ops ft_fabric_ops; | ||||
| 
 | ||||
| static LIST_HEAD(ft_wwn_list); | ||||
| DEFINE_MUTEX(ft_lport_lock); | ||||
| @ -337,7 +337,7 @@ static struct se_portal_group *ft_add_tpg( | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	ret = core_tpg_register(&ft_configfs->tf_ops, wwn, &tpg->se_tpg, | ||||
| 	ret = core_tpg_register(&ft_fabric_ops, wwn, &tpg->se_tpg, | ||||
| 				tpg, TRANSPORT_TPG_TYPE_NORMAL); | ||||
| 	if (ret < 0) { | ||||
| 		destroy_workqueue(wq); | ||||
| @ -507,7 +507,9 @@ static u32 ft_tpg_get_inst_index(struct se_portal_group *se_tpg) | ||||
| 	return tpg->index; | ||||
| } | ||||
| 
 | ||||
| static struct target_core_fabric_ops ft_fabric_ops = { | ||||
| static const struct target_core_fabric_ops ft_fabric_ops = { | ||||
| 	.module =			THIS_MODULE, | ||||
| 	.name =				"fc", | ||||
| 	.get_fabric_name =		ft_get_fabric_name, | ||||
| 	.get_fabric_proto_ident =	fc_get_fabric_proto_ident, | ||||
| 	.tpg_get_wwn =			ft_get_fabric_wwn, | ||||
| @ -552,78 +554,35 @@ static struct target_core_fabric_ops ft_fabric_ops = { | ||||
| 	.fabric_drop_np =		NULL, | ||||
| 	.fabric_make_nodeacl =		&ft_add_acl, | ||||
| 	.fabric_drop_nodeacl =		&ft_del_acl, | ||||
| 
 | ||||
| 	.tfc_wwn_attrs			= ft_wwn_attrs, | ||||
| 	.tfc_tpg_nacl_base_attrs	= ft_nacl_base_attrs, | ||||
| }; | ||||
| 
 | ||||
| static int ft_register_configfs(void) | ||||
| { | ||||
| 	struct target_fabric_configfs *fabric; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Register the top level struct config_item_type with TCM core | ||||
| 	 */ | ||||
| 	fabric = target_fabric_configfs_init(THIS_MODULE, "fc"); | ||||
| 	if (IS_ERR(fabric)) { | ||||
| 		pr_err("%s: target_fabric_configfs_init() failed!\n", | ||||
| 		       __func__); | ||||
| 		return PTR_ERR(fabric); | ||||
| 	} | ||||
| 	fabric->tf_ops = ft_fabric_ops; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Setup default attribute lists for various fabric->tf_cit_tmpl | ||||
| 	 */ | ||||
| 	fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = ft_wwn_attrs; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_param_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_np_base_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_base_cit.ct_attrs = | ||||
| 						    ft_nacl_base_attrs; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_attrib_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_auth_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_param_cit.ct_attrs = NULL; | ||||
| 	/*
 | ||||
| 	 * register the fabric for use within TCM | ||||
| 	 */ | ||||
| 	ret = target_fabric_configfs_register(fabric); | ||||
| 	if (ret < 0) { | ||||
| 		pr_debug("target_fabric_configfs_register() for" | ||||
| 			    " FC Target failed!\n"); | ||||
| 		target_fabric_configfs_free(fabric); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Setup our local pointer to *fabric. | ||||
| 	 */ | ||||
| 	ft_configfs = fabric; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void ft_deregister_configfs(void) | ||||
| { | ||||
| 	if (!ft_configfs) | ||||
| 		return; | ||||
| 	target_fabric_configfs_deregister(ft_configfs); | ||||
| 	ft_configfs = NULL; | ||||
| } | ||||
| 
 | ||||
| static struct notifier_block ft_notifier = { | ||||
| 	.notifier_call = ft_lport_notify | ||||
| }; | ||||
| 
 | ||||
| static int __init ft_init(void) | ||||
| { | ||||
| 	if (ft_register_configfs()) | ||||
| 		return -1; | ||||
| 	if (fc_fc4_register_provider(FC_TYPE_FCP, &ft_prov)) { | ||||
| 		ft_deregister_configfs(); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	int ret; | ||||
| 
 | ||||
| 	ret = target_register_template(&ft_fabric_ops); | ||||
| 	if (ret) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	ret = fc_fc4_register_provider(FC_TYPE_FCP, &ft_prov); | ||||
| 	if (ret) | ||||
| 		goto out_unregister_template; | ||||
| 
 | ||||
| 	blocking_notifier_chain_register(&fc_lport_notifier_head, &ft_notifier); | ||||
| 	fc_lport_iterate(ft_lport_add, NULL); | ||||
| 	return 0; | ||||
| 
 | ||||
| out_unregister_template: | ||||
| 	target_unregister_template(&ft_fabric_ops); | ||||
| out: | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static void __exit ft_exit(void) | ||||
| @ -632,7 +591,7 @@ static void __exit ft_exit(void) | ||||
| 					   &ft_notifier); | ||||
| 	fc_fc4_deregister_provider(FC_TYPE_FCP, &ft_prov); | ||||
| 	fc_lport_iterate(ft_lport_del, NULL); | ||||
| 	ft_deregister_configfs(); | ||||
| 	target_unregister_template(&ft_fabric_ops); | ||||
| 	synchronize_rcu(); | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -29,7 +29,7 @@ | ||||
| 
 | ||||
| USB_GADGET_COMPOSITE_OPTIONS(); | ||||
| 
 | ||||
| static struct target_fabric_configfs *usbg_fabric_configfs; | ||||
| static const struct target_core_fabric_ops usbg_ops; | ||||
| 
 | ||||
| static inline struct f_uas *to_f_uas(struct usb_function *f) | ||||
| { | ||||
| @ -1572,8 +1572,7 @@ static struct se_portal_group *usbg_make_tpg( | ||||
| 	tpg->tport = tport; | ||||
| 	tpg->tport_tpgt = tpgt; | ||||
| 
 | ||||
| 	ret = core_tpg_register(&usbg_fabric_configfs->tf_ops, wwn, | ||||
| 				&tpg->se_tpg, tpg, | ||||
| 	ret = core_tpg_register(&usbg_ops, wwn, &tpg->se_tpg, tpg, | ||||
| 				TRANSPORT_TPG_TYPE_NORMAL); | ||||
| 	if (ret < 0) { | ||||
| 		destroy_workqueue(tpg->workqueue); | ||||
| @ -1865,7 +1864,9 @@ static int usbg_check_stop_free(struct se_cmd *se_cmd) | ||||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| static struct target_core_fabric_ops usbg_ops = { | ||||
| static const struct target_core_fabric_ops usbg_ops = { | ||||
| 	.module				= THIS_MODULE, | ||||
| 	.name				= "usb_gadget", | ||||
| 	.get_fabric_name		= usbg_get_fabric_name, | ||||
| 	.get_fabric_proto_ident		= usbg_get_fabric_proto_ident, | ||||
| 	.tpg_get_wwn			= usbg_get_fabric_wwn, | ||||
| @ -1907,46 +1908,9 @@ static struct target_core_fabric_ops usbg_ops = { | ||||
| 	.fabric_drop_np			= NULL, | ||||
| 	.fabric_make_nodeacl		= usbg_make_nodeacl, | ||||
| 	.fabric_drop_nodeacl		= usbg_drop_nodeacl, | ||||
| }; | ||||
| 
 | ||||
| static int usbg_register_configfs(void) | ||||
| { | ||||
| 	struct target_fabric_configfs *fabric; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	fabric = target_fabric_configfs_init(THIS_MODULE, "usb_gadget"); | ||||
| 	if (IS_ERR(fabric)) { | ||||
| 		printk(KERN_ERR "target_fabric_configfs_init() failed\n"); | ||||
| 		return PTR_ERR(fabric); | ||||
| 	} | ||||
| 
 | ||||
| 	fabric->tf_ops = usbg_ops; | ||||
| 	fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = usbg_wwn_attrs; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = usbg_base_attrs; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_param_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_np_base_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_base_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_attrib_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_auth_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_param_cit.ct_attrs = NULL; | ||||
| 	ret = target_fabric_configfs_register(fabric); | ||||
| 	if (ret < 0) { | ||||
| 		printk(KERN_ERR "target_fabric_configfs_register() failed" | ||||
| 				" for usb-gadget\n"); | ||||
| 		return ret; | ||||
| 	} | ||||
| 	usbg_fabric_configfs = fabric; | ||||
| 	return 0; | ||||
| }; | ||||
| 
 | ||||
| static void usbg_deregister_configfs(void) | ||||
| { | ||||
| 	if (!(usbg_fabric_configfs)) | ||||
| 		return; | ||||
| 
 | ||||
| 	target_fabric_configfs_deregister(usbg_fabric_configfs); | ||||
| 	usbg_fabric_configfs = NULL; | ||||
| 	.tfc_wwn_attrs			= usbg_wwn_attrs, | ||||
| 	.tfc_tpg_base_attrs		= usbg_base_attrs, | ||||
| }; | ||||
| 
 | ||||
| /* Start gadget.c code */ | ||||
| @ -2455,16 +2419,13 @@ static void usbg_detach(struct usbg_tpg *tpg) | ||||
| 
 | ||||
| static int __init usb_target_gadget_init(void) | ||||
| { | ||||
| 	int ret; | ||||
| 
 | ||||
| 	ret = usbg_register_configfs(); | ||||
| 	return ret; | ||||
| 	return target_register_template(&usbg_ops); | ||||
| } | ||||
| module_init(usb_target_gadget_init); | ||||
| 
 | ||||
| static void __exit usb_target_gadget_exit(void) | ||||
| { | ||||
| 	usbg_deregister_configfs(); | ||||
| 	target_unregister_template(&usbg_ops); | ||||
| } | ||||
| module_exit(usb_target_gadget_exit); | ||||
| 
 | ||||
|  | ||||
| @ -216,9 +216,7 @@ struct vhost_scsi { | ||||
| 	int vs_events_nr; /* num of pending events, protected by vq->mutex */ | ||||
| }; | ||||
| 
 | ||||
| /* Local pointer to allocated TCM configfs fabric module */ | ||||
| static struct target_fabric_configfs *vhost_scsi_fabric_configfs; | ||||
| 
 | ||||
| static struct target_core_fabric_ops vhost_scsi_ops; | ||||
| static struct workqueue_struct *vhost_scsi_workqueue; | ||||
| 
 | ||||
| /* Global spinlock to protect vhost_scsi TPG list for vhost IOCTL access */ | ||||
| @ -2205,7 +2203,7 @@ vhost_scsi_make_tpg(struct se_wwn *wwn, | ||||
| 	tpg->tport = tport; | ||||
| 	tpg->tport_tpgt = tpgt; | ||||
| 
 | ||||
| 	ret = core_tpg_register(&vhost_scsi_fabric_configfs->tf_ops, wwn, | ||||
| 	ret = core_tpg_register(&vhost_scsi_ops, wwn, | ||||
| 				&tpg->se_tpg, tpg, TRANSPORT_TPG_TYPE_NORMAL); | ||||
| 	if (ret < 0) { | ||||
| 		kfree(tpg); | ||||
| @ -2327,6 +2325,8 @@ static struct configfs_attribute *vhost_scsi_wwn_attrs[] = { | ||||
| }; | ||||
| 
 | ||||
| static struct target_core_fabric_ops vhost_scsi_ops = { | ||||
| 	.module				= THIS_MODULE, | ||||
| 	.name				= "vhost", | ||||
| 	.get_fabric_name		= vhost_scsi_get_fabric_name, | ||||
| 	.get_fabric_proto_ident		= vhost_scsi_get_fabric_proto_ident, | ||||
| 	.tpg_get_wwn			= vhost_scsi_get_fabric_wwn, | ||||
| @ -2371,70 +2371,20 @@ static struct target_core_fabric_ops vhost_scsi_ops = { | ||||
| 	.fabric_drop_np			= NULL, | ||||
| 	.fabric_make_nodeacl		= vhost_scsi_make_nodeacl, | ||||
| 	.fabric_drop_nodeacl		= vhost_scsi_drop_nodeacl, | ||||
| }; | ||||
| 
 | ||||
| static int vhost_scsi_register_configfs(void) | ||||
| { | ||||
| 	struct target_fabric_configfs *fabric; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	pr_debug("vhost-scsi fabric module %s on %s/%s" | ||||
| 		" on "UTS_RELEASE"\n", VHOST_SCSI_VERSION, utsname()->sysname, | ||||
| 		utsname()->machine); | ||||
| 	/*
 | ||||
| 	 * Register the top level struct config_item_type with TCM core | ||||
| 	 */ | ||||
| 	fabric = target_fabric_configfs_init(THIS_MODULE, "vhost"); | ||||
| 	if (IS_ERR(fabric)) { | ||||
| 		pr_err("target_fabric_configfs_init() failed\n"); | ||||
| 		return PTR_ERR(fabric); | ||||
| 	} | ||||
| 	/*
 | ||||
| 	 * Setup fabric->tf_ops from our local vhost_scsi_ops | ||||
| 	 */ | ||||
| 	fabric->tf_ops = vhost_scsi_ops; | ||||
| 	/*
 | ||||
| 	 * Setup default attribute lists for various fabric->tf_cit_tmpl | ||||
| 	 */ | ||||
| 	fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = vhost_scsi_wwn_attrs; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = vhost_scsi_tpg_attrs; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = vhost_scsi_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; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_base_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_attrib_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_auth_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_param_cit.ct_attrs = NULL; | ||||
| 	/*
 | ||||
| 	 * Register the fabric for use within TCM | ||||
| 	 */ | ||||
| 	ret = target_fabric_configfs_register(fabric); | ||||
| 	if (ret < 0) { | ||||
| 		pr_err("target_fabric_configfs_register() failed" | ||||
| 				" for TCM_VHOST\n"); | ||||
| 		return ret; | ||||
| 	} | ||||
| 	/*
 | ||||
| 	 * Setup our local pointer to *fabric | ||||
| 	 */ | ||||
| 	vhost_scsi_fabric_configfs = fabric; | ||||
| 	pr_debug("TCM_VHOST[0] - Set fabric -> vhost_scsi_fabric_configfs\n"); | ||||
| 	return 0; | ||||
| }; | ||||
| 
 | ||||
| static void vhost_scsi_deregister_configfs(void) | ||||
| { | ||||
| 	if (!vhost_scsi_fabric_configfs) | ||||
| 		return; | ||||
| 
 | ||||
| 	target_fabric_configfs_deregister(vhost_scsi_fabric_configfs); | ||||
| 	vhost_scsi_fabric_configfs = NULL; | ||||
| 	pr_debug("TCM_VHOST[0] - Cleared vhost_scsi_fabric_configfs\n"); | ||||
| 	.tfc_wwn_attrs			= vhost_scsi_wwn_attrs, | ||||
| 	.tfc_tpg_base_attrs		= vhost_scsi_tpg_attrs, | ||||
| 	.tfc_tpg_attrib_attrs		= vhost_scsi_tpg_attrib_attrs, | ||||
| }; | ||||
| 
 | ||||
| static int __init vhost_scsi_init(void) | ||||
| { | ||||
| 	int ret = -ENOMEM; | ||||
| 
 | ||||
| 	pr_debug("TCM_VHOST fabric module %s on %s/%s" | ||||
| 		" on "UTS_RELEASE"\n", VHOST_SCSI_VERSION, utsname()->sysname, | ||||
| 		utsname()->machine); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Use our own dedicated workqueue for submitting I/O into | ||||
| 	 * target core to avoid contention within system_wq. | ||||
| @ -2447,7 +2397,7 @@ static int __init vhost_scsi_init(void) | ||||
| 	if (ret < 0) | ||||
| 		goto out_destroy_workqueue; | ||||
| 
 | ||||
| 	ret = vhost_scsi_register_configfs(); | ||||
| 	ret = target_register_template(&vhost_scsi_ops); | ||||
| 	if (ret < 0) | ||||
| 		goto out_vhost_scsi_deregister; | ||||
| 
 | ||||
| @ -2463,7 +2413,7 @@ out: | ||||
| 
 | ||||
| static void vhost_scsi_exit(void) | ||||
| { | ||||
| 	vhost_scsi_deregister_configfs(); | ||||
| 	target_unregister_template(&vhost_scsi_ops); | ||||
| 	vhost_scsi_deregister(); | ||||
| 	destroy_workqueue(vhost_scsi_workqueue); | ||||
| }; | ||||
|  | ||||
| @ -205,8 +205,7 @@ static LIST_HEAD(scsiback_free_pages); | ||||
| static DEFINE_MUTEX(scsiback_mutex); | ||||
| static LIST_HEAD(scsiback_list); | ||||
| 
 | ||||
| /* Local pointer to allocated TCM configfs fabric module */ | ||||
| static struct target_fabric_configfs *scsiback_fabric_configfs; | ||||
| static const struct target_core_fabric_ops scsiback_ops; | ||||
| 
 | ||||
| static void scsiback_get(struct vscsibk_info *info) | ||||
| { | ||||
| @ -1901,7 +1900,7 @@ scsiback_make_tpg(struct se_wwn *wwn, | ||||
| 	tpg->tport = tport; | ||||
| 	tpg->tport_tpgt = tpgt; | ||||
| 
 | ||||
| 	ret = core_tpg_register(&scsiback_fabric_configfs->tf_ops, wwn, | ||||
| 	ret = core_tpg_register(&scsiback_ops, wwn, | ||||
| 				&tpg->se_tpg, tpg, TRANSPORT_TPG_TYPE_NORMAL); | ||||
| 	if (ret < 0) { | ||||
| 		kfree(tpg); | ||||
| @ -1943,7 +1942,9 @@ static int scsiback_check_false(struct se_portal_group *se_tpg) | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static struct target_core_fabric_ops scsiback_ops = { | ||||
| static const struct target_core_fabric_ops scsiback_ops = { | ||||
| 	.module				= THIS_MODULE, | ||||
| 	.name				= "xen-pvscsi", | ||||
| 	.get_fabric_name		= scsiback_get_fabric_name, | ||||
| 	.get_fabric_proto_ident		= scsiback_get_fabric_proto_ident, | ||||
| 	.tpg_get_wwn			= scsiback_get_fabric_wwn, | ||||
| @ -1990,62 +1991,10 @@ static struct target_core_fabric_ops scsiback_ops = { | ||||
| 	.fabric_make_nodeacl		= scsiback_make_nodeacl, | ||||
| 	.fabric_drop_nodeacl		= scsiback_drop_nodeacl, | ||||
| #endif | ||||
| }; | ||||
| 
 | ||||
| static int scsiback_register_configfs(void) | ||||
| { | ||||
| 	struct target_fabric_configfs *fabric; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	pr_debug("xen-pvscsi: fabric module %s on %s/%s on "UTS_RELEASE"\n", | ||||
| 		 VSCSI_VERSION, utsname()->sysname, utsname()->machine); | ||||
| 	/*
 | ||||
| 	 * Register the top level struct config_item_type with TCM core | ||||
| 	 */ | ||||
| 	fabric = target_fabric_configfs_init(THIS_MODULE, "xen-pvscsi"); | ||||
| 	if (IS_ERR(fabric)) | ||||
| 		return PTR_ERR(fabric); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Setup fabric->tf_ops from our local scsiback_ops | ||||
| 	 */ | ||||
| 	fabric->tf_ops = scsiback_ops; | ||||
| 	/*
 | ||||
| 	 * Setup default attribute lists for various fabric->tf_cit_tmpl | ||||
| 	 */ | ||||
| 	fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = scsiback_wwn_attrs; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = scsiback_tpg_attrs; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_param_cit.ct_attrs = scsiback_param_attrs; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_np_base_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_base_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_attrib_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_auth_cit.ct_attrs = NULL; | ||||
| 	fabric->tf_cit_tmpl.tfc_tpg_nacl_param_cit.ct_attrs = NULL; | ||||
| 	/*
 | ||||
| 	 * Register the fabric for use within TCM | ||||
| 	 */ | ||||
| 	ret = target_fabric_configfs_register(fabric); | ||||
| 	if (ret < 0) { | ||||
| 		target_fabric_configfs_free(fabric); | ||||
| 		return ret; | ||||
| 	} | ||||
| 	/*
 | ||||
| 	 * Setup our local pointer to *fabric | ||||
| 	 */ | ||||
| 	scsiback_fabric_configfs = fabric; | ||||
| 	pr_debug("xen-pvscsi: Set fabric -> scsiback_fabric_configfs\n"); | ||||
| 	return 0; | ||||
| }; | ||||
| 
 | ||||
| static void scsiback_deregister_configfs(void) | ||||
| { | ||||
| 	if (!scsiback_fabric_configfs) | ||||
| 		return; | ||||
| 
 | ||||
| 	target_fabric_configfs_deregister(scsiback_fabric_configfs); | ||||
| 	scsiback_fabric_configfs = NULL; | ||||
| 	pr_debug("xen-pvscsi: Cleared scsiback_fabric_configfs\n"); | ||||
| 	.tfc_wwn_attrs			= scsiback_wwn_attrs, | ||||
| 	.tfc_tpg_base_attrs		= scsiback_tpg_attrs, | ||||
| 	.tfc_tpg_param_attrs		= scsiback_param_attrs, | ||||
| }; | ||||
| 
 | ||||
| static const struct xenbus_device_id scsiback_ids[] = { | ||||
| @ -2077,6 +2026,9 @@ static int __init scsiback_init(void) | ||||
| 	if (!xen_domain()) | ||||
| 		return -ENODEV; | ||||
| 
 | ||||
| 	pr_debug("xen-pvscsi: fabric module %s on %s/%s on "UTS_RELEASE"\n", | ||||
| 		 VSCSI_VERSION, utsname()->sysname, utsname()->machine); | ||||
| 
 | ||||
| 	scsiback_cachep = kmem_cache_create("vscsiif_cache", | ||||
| 		sizeof(struct vscsibk_pend), 0, 0, scsiback_init_pend); | ||||
| 	if (!scsiback_cachep) | ||||
| @ -2086,7 +2038,7 @@ static int __init scsiback_init(void) | ||||
| 	if (ret) | ||||
| 		goto out_cache_destroy; | ||||
| 
 | ||||
| 	ret = scsiback_register_configfs(); | ||||
| 	ret = target_register_template(&scsiback_ops); | ||||
| 	if (ret) | ||||
| 		goto out_unregister_xenbus; | ||||
| 
 | ||||
| @ -2109,7 +2061,7 @@ static void __exit scsiback_exit(void) | ||||
| 			BUG(); | ||||
| 		gnttab_free_pages(1, &page); | ||||
| 	} | ||||
| 	scsiback_deregister_configfs(); | ||||
| 	target_unregister_template(&scsiback_ops); | ||||
| 	xenbus_unregister_driver(&scsiback_driver); | ||||
| 	kmem_cache_destroy(scsiback_cachep); | ||||
| } | ||||
|  | ||||
| @ -519,7 +519,7 @@ struct se_cmd { | ||||
| 	struct list_head	se_cmd_list; | ||||
| 	struct completion	cmd_wait_comp; | ||||
| 	struct kref		cmd_kref; | ||||
| 	struct target_core_fabric_ops *se_tfo; | ||||
| 	const struct target_core_fabric_ops *se_tfo; | ||||
| 	sense_reason_t		(*execute_cmd)(struct se_cmd *); | ||||
| 	sense_reason_t		(*execute_rw)(struct se_cmd *, struct scatterlist *, | ||||
| 					      u32, enum dma_data_direction); | ||||
| @ -890,7 +890,7 @@ struct se_portal_group { | ||||
| 	/* List of TCM sessions associated wth this TPG */ | ||||
| 	struct list_head	tpg_sess_list; | ||||
| 	/* Pointer to $FABRIC_MOD dependent code */ | ||||
| 	struct target_core_fabric_ops *se_tpg_tfo; | ||||
| 	const struct target_core_fabric_ops *se_tpg_tfo; | ||||
| 	struct se_wwn		*se_tpg_wwn; | ||||
| 	struct config_group	tpg_group; | ||||
| 	struct config_group	*tpg_default_groups[7]; | ||||
|  | ||||
| @ -5,12 +5,6 @@ | ||||
| #define TARGET_CORE_NAME_MAX_LEN	64 | ||||
| #define TARGET_FABRIC_NAME_SIZE		32 | ||||
| 
 | ||||
| extern struct target_fabric_configfs *target_fabric_configfs_init( | ||||
| 				struct module *, const char *); | ||||
| extern void target_fabric_configfs_free(struct target_fabric_configfs *); | ||||
| extern int target_fabric_configfs_register(struct target_fabric_configfs *); | ||||
| extern void target_fabric_configfs_deregister(struct target_fabric_configfs *); | ||||
| 
 | ||||
| struct target_fabric_configfs_template { | ||||
| 	struct config_item_type tfc_discovery_cit; | ||||
| 	struct config_item_type	tfc_wwn_cit; | ||||
|  | ||||
| @ -2,6 +2,8 @@ | ||||
| #define TARGET_CORE_FABRIC_H | ||||
| 
 | ||||
| struct target_core_fabric_ops { | ||||
| 	struct module *module; | ||||
| 	const char *name; | ||||
| 	struct configfs_subsystem *tf_subsys; | ||||
| 	char *(*get_fabric_name)(void); | ||||
| 	u8 (*get_fabric_proto_ident)(struct se_portal_group *); | ||||
| @ -90,8 +92,23 @@ struct target_core_fabric_ops { | ||||
| 	struct se_node_acl *(*fabric_make_nodeacl)(struct se_portal_group *, | ||||
| 				struct config_group *, const char *); | ||||
| 	void (*fabric_drop_nodeacl)(struct se_node_acl *); | ||||
| 
 | ||||
| 	struct configfs_attribute **tfc_discovery_attrs; | ||||
| 	struct configfs_attribute **tfc_wwn_attrs; | ||||
| 	struct configfs_attribute **tfc_tpg_base_attrs; | ||||
| 	struct configfs_attribute **tfc_tpg_np_base_attrs; | ||||
| 	struct configfs_attribute **tfc_tpg_attrib_attrs; | ||||
| 	struct configfs_attribute **tfc_tpg_auth_attrs; | ||||
| 	struct configfs_attribute **tfc_tpg_param_attrs; | ||||
| 	struct configfs_attribute **tfc_tpg_nacl_base_attrs; | ||||
| 	struct configfs_attribute **tfc_tpg_nacl_attrib_attrs; | ||||
| 	struct configfs_attribute **tfc_tpg_nacl_auth_attrs; | ||||
| 	struct configfs_attribute **tfc_tpg_nacl_param_attrs; | ||||
| }; | ||||
| 
 | ||||
| int target_register_template(const struct target_core_fabric_ops *fo); | ||||
| void target_unregister_template(const struct target_core_fabric_ops *fo); | ||||
| 
 | ||||
| struct se_session *transport_init_session(enum target_prot_op); | ||||
| int transport_alloc_session_tags(struct se_session *, unsigned int, | ||||
| 		unsigned int); | ||||
| @ -110,7 +127,8 @@ void	transport_deregister_session_configfs(struct se_session *); | ||||
| void	transport_deregister_session(struct se_session *); | ||||
| 
 | ||||
| 
 | ||||
| void	transport_init_se_cmd(struct se_cmd *, struct target_core_fabric_ops *, | ||||
| void	transport_init_se_cmd(struct se_cmd *, | ||||
| 		const struct target_core_fabric_ops *, | ||||
| 		struct se_session *, u32, int, int, unsigned char *); | ||||
| sense_reason_t transport_lookup_cmd_lun(struct se_cmd *, u32); | ||||
| sense_reason_t target_setup_cmd_from_cdb(struct se_cmd *, unsigned char *); | ||||
| @ -162,8 +180,8 @@ int	core_tpg_set_initiator_node_queue_depth(struct se_portal_group *, | ||||
| 		unsigned char *, u32, int); | ||||
| int	core_tpg_set_initiator_node_tag(struct se_portal_group *, | ||||
| 		struct se_node_acl *, const char *); | ||||
| int	core_tpg_register(struct target_core_fabric_ops *, struct se_wwn *, | ||||
| 		struct se_portal_group *, void *, int); | ||||
| int	core_tpg_register(const struct target_core_fabric_ops *, | ||||
| 		struct se_wwn *, struct se_portal_group *, void *, int); | ||||
| int	core_tpg_deregister(struct se_portal_group *); | ||||
| 
 | ||||
| /* SAS helpers */ | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user