Commit 80ed33c8 authored by Dmitry Bogdanov's avatar Dmitry Bogdanov Committed by Martin K. Petersen
Browse files

scsi: target: core: Add common tpg/enable attribute

Many fabric modules provide their own implementation of enable attribute in
tpg.

Provide a way to remove code duplication in the fabric modules and
automatically add "enable" attribute if a fabric module has an
implementation of fabric_enable_tpg().

Link: https://lore.kernel.org/r/20210910084133.17956-2-d.bogdanov@yadro.com


Reviewed-by: default avatarRoman Bolshakov <r.bolshakov@yadro.com>
Reviewed-by: default avatarMike Christie <michael.christie@oracle.com>
Signed-off-by: default avatarDmitry Bogdanov <d.bogdanov@yadro.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent cdf7f6a1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -490,6 +490,7 @@ void target_unregister_template(const struct target_core_fabric_ops *fo)
			 * fabric driver unload of TFO->module to proceed.
			 */
			rcu_barrier();
			kfree(t->tf_tpg_base_cit.ct_attrs);
			kfree(t);
			return;
		}
+76 −2
Original line number Diff line number Diff line
@@ -815,8 +815,76 @@ static struct configfs_item_operations target_fabric_tpg_base_item_ops = {
	.release		= target_fabric_tpg_release,
};

TF_CIT_SETUP_DRV(tpg_base, &target_fabric_tpg_base_item_ops, NULL);
static ssize_t target_fabric_tpg_base_enable_show(struct config_item *item,
						  char *page)
{
	return sysfs_emit(page, "%d\n", to_tpg(item)->enabled);
}

static ssize_t target_fabric_tpg_base_enable_store(struct config_item *item,
						   const char *page,
						   size_t count)
{
	struct se_portal_group *se_tpg = to_tpg(item);
	int ret;
	bool op;

	ret = strtobool(page, &op);
	if (ret)
		return ret;

	if (se_tpg->enabled == op)
		return count;

	ret = se_tpg->se_tpg_tfo->fabric_enable_tpg(se_tpg, op);
	if (ret)
		return ret;

	se_tpg->enabled = op;

	return count;
}

CONFIGFS_ATTR(target_fabric_tpg_base_, enable);

static int
target_fabric_setup_tpg_base_cit(struct target_fabric_configfs *tf)
{
	struct config_item_type *cit = &tf->tf_tpg_base_cit;
	struct configfs_attribute **attrs = NULL;
	size_t nr_attrs = 0;
	int i = 0;

	if (tf->tf_ops->tfc_tpg_base_attrs)
		while (tf->tf_ops->tfc_tpg_base_attrs[nr_attrs] != NULL)
			nr_attrs++;

	if (tf->tf_ops->fabric_enable_tpg)
		nr_attrs++;

	if (nr_attrs == 0)
		goto done;

	/* + 1 for final NULL in the array */
	attrs = kcalloc(nr_attrs + 1, sizeof(*attrs), GFP_KERNEL);
	if (!attrs)
		return -ENOMEM;

	if (tf->tf_ops->tfc_tpg_base_attrs)
		for (; tf->tf_ops->tfc_tpg_base_attrs[i] != NULL; i++)
			attrs[i] = tf->tf_ops->tfc_tpg_base_attrs[i];

	if (tf->tf_ops->fabric_enable_tpg)
		attrs[i] = &target_fabric_tpg_base_attr_enable;

done:
	cit->ct_item_ops = &target_fabric_tpg_base_item_ops;
	cit->ct_attrs = attrs;
	cit->ct_owner = tf->tf_ops->module;
	pr_debug("Setup generic tpg_base\n");

	return 0;
}
/* End of tfc_tpg_base_cit */

/* Start of tfc_tpg_cit */
@@ -1028,12 +1096,18 @@ TF_CIT_SETUP_DRV(discovery, NULL, NULL);

int target_fabric_setup_cits(struct target_fabric_configfs *tf)
{
	int ret;

	target_fabric_setup_discovery_cit(tf);
	target_fabric_setup_wwn_cit(tf);
	target_fabric_setup_wwn_fabric_stats_cit(tf);
	target_fabric_setup_wwn_param_cit(tf);
	target_fabric_setup_tpg_cit(tf);
	target_fabric_setup_tpg_base_cit(tf);

	ret = target_fabric_setup_tpg_base_cit(tf);
	if (ret)
		return ret;

	target_fabric_setup_tpg_port_cit(tf);
	target_fabric_setup_tpg_port_stat_cit(tf);
	target_fabric_setup_tpg_lun_cit(tf);
+1 −0
Original line number Diff line number Diff line
@@ -900,6 +900,7 @@ struct se_portal_group {
	 * Negative values can be used by fabric drivers for internal use TPGs.
	 */
	int			proto_id;
	bool			enabled;
	/* Used for PR SPEC_I_PT=1 and REGISTER_AND_MOVE */
	atomic_t		tpg_pr_ref_count;
	/* Spinlock for adding/removing ACLed Nodes */
+1 −0
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ struct target_core_fabric_ops {
	void (*add_wwn_groups)(struct se_wwn *);
	struct se_portal_group *(*fabric_make_tpg)(struct se_wwn *,
						   const char *);
	int (*fabric_enable_tpg)(struct se_portal_group *se_tpg, bool enable);
	void (*fabric_drop_tpg)(struct se_portal_group *);
	int (*fabric_post_link)(struct se_portal_group *,
				struct se_lun *);