cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

target_core_fabric_configfs.c (31096B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*******************************************************************************
      3* Filename: target_core_fabric_configfs.c
      4 *
      5 * This file contains generic fabric module configfs infrastructure for
      6 * TCM v4.x code
      7 *
      8 * (c) Copyright 2010-2013 Datera, Inc.
      9 *
     10 * Nicholas A. Bellinger <nab@linux-iscsi.org>
     11*
     12 ****************************************************************************/
     13
     14#include <linux/module.h>
     15#include <linux/moduleparam.h>
     16#include <linux/utsname.h>
     17#include <linux/init.h>
     18#include <linux/fs.h>
     19#include <linux/namei.h>
     20#include <linux/slab.h>
     21#include <linux/types.h>
     22#include <linux/delay.h>
     23#include <linux/unistd.h>
     24#include <linux/string.h>
     25#include <linux/syscalls.h>
     26#include <linux/configfs.h>
     27
     28#include <target/target_core_base.h>
     29#include <target/target_core_backend.h>
     30#include <target/target_core_fabric.h>
     31
     32#include "target_core_internal.h"
     33#include "target_core_alua.h"
     34#include "target_core_pr.h"
     35
     36#define TF_CIT_SETUP(_name, _item_ops, _group_ops, _attrs)		\
     37static void target_fabric_setup_##_name##_cit(struct target_fabric_configfs *tf) \
     38{									\
     39	struct config_item_type *cit = &tf->tf_##_name##_cit;		\
     40									\
     41	cit->ct_item_ops = _item_ops;					\
     42	cit->ct_group_ops = _group_ops;					\
     43	cit->ct_attrs = _attrs;						\
     44	cit->ct_owner = tf->tf_ops->module;				\
     45	pr_debug("Setup generic %s\n", __stringify(_name));		\
     46}
     47
     48#define TF_CIT_SETUP_DRV(_name, _item_ops, _group_ops)		\
     49static void target_fabric_setup_##_name##_cit(struct target_fabric_configfs *tf) \
     50{									\
     51	struct config_item_type *cit = &tf->tf_##_name##_cit;		\
     52	struct configfs_attribute **attrs = tf->tf_ops->tfc_##_name##_attrs; \
     53									\
     54	cit->ct_item_ops = _item_ops;					\
     55	cit->ct_group_ops = _group_ops;					\
     56	cit->ct_attrs = attrs;						\
     57	cit->ct_owner = tf->tf_ops->module;				\
     58	pr_debug("Setup generic %s\n", __stringify(_name));		\
     59}
     60
     61static struct configfs_item_operations target_fabric_port_item_ops;
     62
     63/* Start of tfc_tpg_mappedlun_cit */
     64
     65static int target_fabric_mappedlun_link(
     66	struct config_item *lun_acl_ci,
     67	struct config_item *lun_ci)
     68{
     69	struct se_dev_entry *deve;
     70	struct se_lun *lun;
     71	struct se_lun_acl *lacl = container_of(to_config_group(lun_acl_ci),
     72			struct se_lun_acl, se_lun_group);
     73	struct se_portal_group *se_tpg;
     74	struct config_item *nacl_ci, *tpg_ci, *tpg_ci_s, *wwn_ci, *wwn_ci_s;
     75	bool lun_access_ro;
     76
     77	if (!lun_ci->ci_type ||
     78	    lun_ci->ci_type->ct_item_ops != &target_fabric_port_item_ops) {
     79		pr_err("Bad lun_ci, not a valid lun_ci pointer: %p\n", lun_ci);
     80		return -EFAULT;
     81	}
     82	lun = container_of(to_config_group(lun_ci), struct se_lun, lun_group);
     83
     84	/*
     85	 * Ensure that the source port exists
     86	 */
     87	if (!lun->lun_se_dev) {
     88		pr_err("Source se_lun->lun_se_dev does not exist\n");
     89		return -EINVAL;
     90	}
     91	if (lun->lun_shutdown) {
     92		pr_err("Unable to create mappedlun symlink because"
     93			" lun->lun_shutdown=true\n");
     94		return -EINVAL;
     95	}
     96	se_tpg = lun->lun_tpg;
     97
     98	nacl_ci = &lun_acl_ci->ci_parent->ci_group->cg_item;
     99	tpg_ci = &nacl_ci->ci_group->cg_item;
    100	wwn_ci = &tpg_ci->ci_group->cg_item;
    101	tpg_ci_s = &lun_ci->ci_parent->ci_group->cg_item;
    102	wwn_ci_s = &tpg_ci_s->ci_group->cg_item;
    103	/*
    104	 * Make sure the SymLink is going to the same $FABRIC/$WWN/tpgt_$TPGT
    105	 */
    106	if (strcmp(config_item_name(wwn_ci), config_item_name(wwn_ci_s))) {
    107		pr_err("Illegal Initiator ACL SymLink outside of %s\n",
    108			config_item_name(wwn_ci));
    109		return -EINVAL;
    110	}
    111	if (strcmp(config_item_name(tpg_ci), config_item_name(tpg_ci_s))) {
    112		pr_err("Illegal Initiator ACL Symlink outside of %s"
    113			" TPGT: %s\n", config_item_name(wwn_ci),
    114			config_item_name(tpg_ci));
    115		return -EINVAL;
    116	}
    117	/*
    118	 * If this struct se_node_acl was dynamically generated with
    119	 * tpg_1/attrib/generate_node_acls=1, use the existing
    120	 * deve->lun_access_ro value, which will be true when
    121	 * tpg_1/attrib/demo_mode_write_protect=1
    122	 */
    123	rcu_read_lock();
    124	deve = target_nacl_find_deve(lacl->se_lun_nacl, lacl->mapped_lun);
    125	if (deve)
    126		lun_access_ro = deve->lun_access_ro;
    127	else
    128		lun_access_ro =
    129			(se_tpg->se_tpg_tfo->tpg_check_prod_mode_write_protect(
    130				se_tpg)) ? true : false;
    131	rcu_read_unlock();
    132	/*
    133	 * Determine the actual mapped LUN value user wants..
    134	 *
    135	 * This value is what the SCSI Initiator actually sees the
    136	 * $FABRIC/$WWPN/$TPGT/lun/lun_* as on their SCSI Initiator Ports.
    137	 */
    138	return core_dev_add_initiator_node_lun_acl(se_tpg, lacl, lun, lun_access_ro);
    139}
    140
    141static void target_fabric_mappedlun_unlink(
    142	struct config_item *lun_acl_ci,
    143	struct config_item *lun_ci)
    144{
    145	struct se_lun_acl *lacl = container_of(to_config_group(lun_acl_ci),
    146			struct se_lun_acl, se_lun_group);
    147	struct se_lun *lun = container_of(to_config_group(lun_ci),
    148			struct se_lun, lun_group);
    149
    150	core_dev_del_initiator_node_lun_acl(lun, lacl);
    151}
    152
    153static struct se_lun_acl *item_to_lun_acl(struct config_item *item)
    154{
    155	return container_of(to_config_group(item), struct se_lun_acl,
    156			se_lun_group);
    157}
    158
    159static ssize_t target_fabric_mappedlun_write_protect_show(
    160		struct config_item *item, char *page)
    161{
    162	struct se_lun_acl *lacl = item_to_lun_acl(item);
    163	struct se_node_acl *se_nacl = lacl->se_lun_nacl;
    164	struct se_dev_entry *deve;
    165	ssize_t len = 0;
    166
    167	rcu_read_lock();
    168	deve = target_nacl_find_deve(se_nacl, lacl->mapped_lun);
    169	if (deve) {
    170		len = sprintf(page, "%d\n", deve->lun_access_ro);
    171	}
    172	rcu_read_unlock();
    173
    174	return len;
    175}
    176
    177static ssize_t target_fabric_mappedlun_write_protect_store(
    178		struct config_item *item, const char *page, size_t count)
    179{
    180	struct se_lun_acl *lacl = item_to_lun_acl(item);
    181	struct se_node_acl *se_nacl = lacl->se_lun_nacl;
    182	struct se_portal_group *se_tpg = se_nacl->se_tpg;
    183	unsigned long wp;
    184	int ret;
    185
    186	ret = kstrtoul(page, 0, &wp);
    187	if (ret)
    188		return ret;
    189
    190	if ((wp != 1) && (wp != 0))
    191		return -EINVAL;
    192
    193	/* wp=1 means lun_access_ro=true */
    194	core_update_device_list_access(lacl->mapped_lun, wp, lacl->se_lun_nacl);
    195
    196	pr_debug("%s_ConfigFS: Changed Initiator ACL: %s"
    197		" Mapped LUN: %llu Write Protect bit to %s\n",
    198		se_tpg->se_tpg_tfo->fabric_name,
    199		se_nacl->initiatorname, lacl->mapped_lun, (wp) ? "ON" : "OFF");
    200
    201	return count;
    202
    203}
    204
    205CONFIGFS_ATTR(target_fabric_mappedlun_, write_protect);
    206
    207static struct configfs_attribute *target_fabric_mappedlun_attrs[] = {
    208	&target_fabric_mappedlun_attr_write_protect,
    209	NULL,
    210};
    211
    212static void target_fabric_mappedlun_release(struct config_item *item)
    213{
    214	struct se_lun_acl *lacl = container_of(to_config_group(item),
    215				struct se_lun_acl, se_lun_group);
    216	struct se_portal_group *se_tpg = lacl->se_lun_nacl->se_tpg;
    217
    218	core_dev_free_initiator_node_lun_acl(se_tpg, lacl);
    219}
    220
    221static struct configfs_item_operations target_fabric_mappedlun_item_ops = {
    222	.release		= target_fabric_mappedlun_release,
    223	.allow_link		= target_fabric_mappedlun_link,
    224	.drop_link		= target_fabric_mappedlun_unlink,
    225};
    226
    227TF_CIT_SETUP(tpg_mappedlun, &target_fabric_mappedlun_item_ops, NULL,
    228		target_fabric_mappedlun_attrs);
    229
    230/* End of tfc_tpg_mappedlun_cit */
    231
    232/* Start of tfc_tpg_mappedlun_port_cit */
    233
    234static struct config_group *target_core_mappedlun_stat_mkdir(
    235	struct config_group *group,
    236	const char *name)
    237{
    238	return ERR_PTR(-ENOSYS);
    239}
    240
    241static void target_core_mappedlun_stat_rmdir(
    242	struct config_group *group,
    243	struct config_item *item)
    244{
    245	return;
    246}
    247
    248static struct configfs_group_operations target_fabric_mappedlun_stat_group_ops = {
    249	.make_group		= target_core_mappedlun_stat_mkdir,
    250	.drop_item		= target_core_mappedlun_stat_rmdir,
    251};
    252
    253TF_CIT_SETUP(tpg_mappedlun_stat, NULL, &target_fabric_mappedlun_stat_group_ops,
    254		NULL);
    255
    256/* End of tfc_tpg_mappedlun_port_cit */
    257
    258TF_CIT_SETUP_DRV(tpg_nacl_attrib, NULL, NULL);
    259TF_CIT_SETUP_DRV(tpg_nacl_auth, NULL, NULL);
    260TF_CIT_SETUP_DRV(tpg_nacl_param, NULL, NULL);
    261
    262/* Start of tfc_tpg_nacl_base_cit */
    263
    264static struct config_group *target_fabric_make_mappedlun(
    265	struct config_group *group,
    266	const char *name)
    267{
    268	struct se_node_acl *se_nacl = container_of(group,
    269			struct se_node_acl, acl_group);
    270	struct se_portal_group *se_tpg = se_nacl->se_tpg;
    271	struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
    272	struct se_lun_acl *lacl = NULL;
    273	char *buf;
    274	unsigned long long mapped_lun;
    275	int ret = 0;
    276
    277	buf = kzalloc(strlen(name) + 1, GFP_KERNEL);
    278	if (!buf) {
    279		pr_err("Unable to allocate memory for name buf\n");
    280		return ERR_PTR(-ENOMEM);
    281	}
    282	snprintf(buf, strlen(name) + 1, "%s", name);
    283	/*
    284	 * Make sure user is creating iscsi/$IQN/$TPGT/acls/$INITIATOR/lun_$ID.
    285	 */
    286	if (strstr(buf, "lun_") != buf) {
    287		pr_err("Unable to locate \"lun_\" from buf: %s"
    288			" name: %s\n", buf, name);
    289		ret = -EINVAL;
    290		goto out;
    291	}
    292	/*
    293	 * Determine the Mapped LUN value.  This is what the SCSI Initiator
    294	 * Port will actually see.
    295	 */
    296	ret = kstrtoull(buf + 4, 0, &mapped_lun);
    297	if (ret)
    298		goto out;
    299
    300	lacl = core_dev_init_initiator_node_lun_acl(se_tpg, se_nacl,
    301			mapped_lun, &ret);
    302	if (!lacl) {
    303		ret = -EINVAL;
    304		goto out;
    305	}
    306
    307	config_group_init_type_name(&lacl->se_lun_group, name,
    308			&tf->tf_tpg_mappedlun_cit);
    309
    310	config_group_init_type_name(&lacl->ml_stat_grps.stat_group,
    311			"statistics", &tf->tf_tpg_mappedlun_stat_cit);
    312	configfs_add_default_group(&lacl->ml_stat_grps.stat_group,
    313			&lacl->se_lun_group);
    314
    315	target_stat_setup_mappedlun_default_groups(lacl);
    316
    317	kfree(buf);
    318	return &lacl->se_lun_group;
    319out:
    320	kfree(lacl);
    321	kfree(buf);
    322	return ERR_PTR(ret);
    323}
    324
    325static void target_fabric_drop_mappedlun(
    326	struct config_group *group,
    327	struct config_item *item)
    328{
    329	struct se_lun_acl *lacl = container_of(to_config_group(item),
    330			struct se_lun_acl, se_lun_group);
    331
    332	configfs_remove_default_groups(&lacl->ml_stat_grps.stat_group);
    333	configfs_remove_default_groups(&lacl->se_lun_group);
    334
    335	config_item_put(item);
    336}
    337
    338static void target_fabric_nacl_base_release(struct config_item *item)
    339{
    340	struct se_node_acl *se_nacl = container_of(to_config_group(item),
    341			struct se_node_acl, acl_group);
    342
    343	configfs_remove_default_groups(&se_nacl->acl_fabric_stat_group);
    344	core_tpg_del_initiator_node_acl(se_nacl);
    345}
    346
    347static struct configfs_item_operations target_fabric_nacl_base_item_ops = {
    348	.release		= target_fabric_nacl_base_release,
    349};
    350
    351static struct configfs_group_operations target_fabric_nacl_base_group_ops = {
    352	.make_group		= target_fabric_make_mappedlun,
    353	.drop_item		= target_fabric_drop_mappedlun,
    354};
    355
    356TF_CIT_SETUP_DRV(tpg_nacl_base, &target_fabric_nacl_base_item_ops,
    357		&target_fabric_nacl_base_group_ops);
    358
    359/* End of tfc_tpg_nacl_base_cit */
    360
    361/* Start of tfc_node_fabric_stats_cit */
    362/*
    363 * This is used as a placeholder for struct se_node_acl->acl_fabric_stat_group
    364 * to allow fabrics access to ->acl_fabric_stat_group->default_groups[]
    365 */
    366TF_CIT_SETUP(tpg_nacl_stat, NULL, NULL, NULL);
    367
    368/* End of tfc_wwn_fabric_stats_cit */
    369
    370/* Start of tfc_tpg_nacl_cit */
    371
    372static struct config_group *target_fabric_make_nodeacl(
    373	struct config_group *group,
    374	const char *name)
    375{
    376	struct se_portal_group *se_tpg = container_of(group,
    377			struct se_portal_group, tpg_acl_group);
    378	struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
    379	struct se_node_acl *se_nacl;
    380
    381	se_nacl = core_tpg_add_initiator_node_acl(se_tpg, name);
    382	if (IS_ERR(se_nacl))
    383		return ERR_CAST(se_nacl);
    384
    385	config_group_init_type_name(&se_nacl->acl_group, name,
    386			&tf->tf_tpg_nacl_base_cit);
    387
    388	config_group_init_type_name(&se_nacl->acl_attrib_group, "attrib",
    389			&tf->tf_tpg_nacl_attrib_cit);
    390	configfs_add_default_group(&se_nacl->acl_attrib_group,
    391			&se_nacl->acl_group);
    392
    393	config_group_init_type_name(&se_nacl->acl_auth_group, "auth",
    394			&tf->tf_tpg_nacl_auth_cit);
    395	configfs_add_default_group(&se_nacl->acl_auth_group,
    396			&se_nacl->acl_group);
    397
    398	config_group_init_type_name(&se_nacl->acl_param_group, "param",
    399			&tf->tf_tpg_nacl_param_cit);
    400	configfs_add_default_group(&se_nacl->acl_param_group,
    401			&se_nacl->acl_group);
    402
    403	config_group_init_type_name(&se_nacl->acl_fabric_stat_group,
    404			"fabric_statistics", &tf->tf_tpg_nacl_stat_cit);
    405	configfs_add_default_group(&se_nacl->acl_fabric_stat_group,
    406			&se_nacl->acl_group);
    407
    408	if (tf->tf_ops->fabric_init_nodeacl) {
    409		int ret = tf->tf_ops->fabric_init_nodeacl(se_nacl, name);
    410		if (ret) {
    411			configfs_remove_default_groups(&se_nacl->acl_fabric_stat_group);
    412			core_tpg_del_initiator_node_acl(se_nacl);
    413			return ERR_PTR(ret);
    414		}
    415	}
    416
    417	return &se_nacl->acl_group;
    418}
    419
    420static void target_fabric_drop_nodeacl(
    421	struct config_group *group,
    422	struct config_item *item)
    423{
    424	struct se_node_acl *se_nacl = container_of(to_config_group(item),
    425			struct se_node_acl, acl_group);
    426
    427	configfs_remove_default_groups(&se_nacl->acl_group);
    428
    429	/*
    430	 * struct se_node_acl free is done in target_fabric_nacl_base_release()
    431	 */
    432	config_item_put(item);
    433}
    434
    435static struct configfs_group_operations target_fabric_nacl_group_ops = {
    436	.make_group	= target_fabric_make_nodeacl,
    437	.drop_item	= target_fabric_drop_nodeacl,
    438};
    439
    440TF_CIT_SETUP(tpg_nacl, NULL, &target_fabric_nacl_group_ops, NULL);
    441
    442/* End of tfc_tpg_nacl_cit */
    443
    444/* Start of tfc_tpg_np_base_cit */
    445
    446static void target_fabric_np_base_release(struct config_item *item)
    447{
    448	struct se_tpg_np *se_tpg_np = container_of(to_config_group(item),
    449				struct se_tpg_np, tpg_np_group);
    450	struct se_portal_group *se_tpg = se_tpg_np->tpg_np_parent;
    451	struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
    452
    453	tf->tf_ops->fabric_drop_np(se_tpg_np);
    454}
    455
    456static struct configfs_item_operations target_fabric_np_base_item_ops = {
    457	.release		= target_fabric_np_base_release,
    458};
    459
    460TF_CIT_SETUP_DRV(tpg_np_base, &target_fabric_np_base_item_ops, NULL);
    461
    462/* End of tfc_tpg_np_base_cit */
    463
    464/* Start of tfc_tpg_np_cit */
    465
    466static struct config_group *target_fabric_make_np(
    467	struct config_group *group,
    468	const char *name)
    469{
    470	struct se_portal_group *se_tpg = container_of(group,
    471				struct se_portal_group, tpg_np_group);
    472	struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
    473	struct se_tpg_np *se_tpg_np;
    474
    475	if (!tf->tf_ops->fabric_make_np) {
    476		pr_err("tf->tf_ops.fabric_make_np is NULL\n");
    477		return ERR_PTR(-ENOSYS);
    478	}
    479
    480	se_tpg_np = tf->tf_ops->fabric_make_np(se_tpg, group, name);
    481	if (!se_tpg_np || IS_ERR(se_tpg_np))
    482		return ERR_PTR(-EINVAL);
    483
    484	se_tpg_np->tpg_np_parent = se_tpg;
    485	config_group_init_type_name(&se_tpg_np->tpg_np_group, name,
    486			&tf->tf_tpg_np_base_cit);
    487
    488	return &se_tpg_np->tpg_np_group;
    489}
    490
    491static void target_fabric_drop_np(
    492	struct config_group *group,
    493	struct config_item *item)
    494{
    495	/*
    496	 * struct se_tpg_np is released via target_fabric_np_base_release()
    497	 */
    498	config_item_put(item);
    499}
    500
    501static struct configfs_group_operations target_fabric_np_group_ops = {
    502	.make_group	= &target_fabric_make_np,
    503	.drop_item	= &target_fabric_drop_np,
    504};
    505
    506TF_CIT_SETUP(tpg_np, NULL, &target_fabric_np_group_ops, NULL);
    507
    508/* End of tfc_tpg_np_cit */
    509
    510/* Start of tfc_tpg_port_cit */
    511
    512static struct se_lun *item_to_lun(struct config_item *item)
    513{
    514	return container_of(to_config_group(item), struct se_lun,
    515			lun_group);
    516}
    517
    518static ssize_t target_fabric_port_alua_tg_pt_gp_show(struct config_item *item,
    519		char *page)
    520{
    521	struct se_lun *lun = item_to_lun(item);
    522
    523	if (!lun->lun_se_dev)
    524		return -ENODEV;
    525
    526	return core_alua_show_tg_pt_gp_info(lun, page);
    527}
    528
    529static ssize_t target_fabric_port_alua_tg_pt_gp_store(struct config_item *item,
    530		const char *page, size_t count)
    531{
    532	struct se_lun *lun = item_to_lun(item);
    533
    534	if (!lun->lun_se_dev)
    535		return -ENODEV;
    536
    537	return core_alua_store_tg_pt_gp_info(lun, page, count);
    538}
    539
    540static ssize_t target_fabric_port_alua_tg_pt_offline_show(
    541		struct config_item *item, char *page)
    542{
    543	struct se_lun *lun = item_to_lun(item);
    544
    545	if (!lun->lun_se_dev)
    546		return -ENODEV;
    547
    548	return core_alua_show_offline_bit(lun, page);
    549}
    550
    551static ssize_t target_fabric_port_alua_tg_pt_offline_store(
    552		struct config_item *item, const char *page, size_t count)
    553{
    554	struct se_lun *lun = item_to_lun(item);
    555
    556	if (!lun->lun_se_dev)
    557		return -ENODEV;
    558
    559	return core_alua_store_offline_bit(lun, page, count);
    560}
    561
    562static ssize_t target_fabric_port_alua_tg_pt_status_show(
    563		struct config_item *item, char *page)
    564{
    565	struct se_lun *lun = item_to_lun(item);
    566
    567	if (!lun->lun_se_dev)
    568		return -ENODEV;
    569
    570	return core_alua_show_secondary_status(lun, page);
    571}
    572
    573static ssize_t target_fabric_port_alua_tg_pt_status_store(
    574		struct config_item *item, const char *page, size_t count)
    575{
    576	struct se_lun *lun = item_to_lun(item);
    577
    578	if (!lun->lun_se_dev)
    579		return -ENODEV;
    580
    581	return core_alua_store_secondary_status(lun, page, count);
    582}
    583
    584static ssize_t target_fabric_port_alua_tg_pt_write_md_show(
    585		struct config_item *item, char *page)
    586{
    587	struct se_lun *lun = item_to_lun(item);
    588
    589	if (!lun->lun_se_dev)
    590		return -ENODEV;
    591
    592	return core_alua_show_secondary_write_metadata(lun, page);
    593}
    594
    595static ssize_t target_fabric_port_alua_tg_pt_write_md_store(
    596		struct config_item *item, const char *page, size_t count)
    597{
    598	struct se_lun *lun = item_to_lun(item);
    599
    600	if (!lun->lun_se_dev)
    601		return -ENODEV;
    602
    603	return core_alua_store_secondary_write_metadata(lun, page, count);
    604}
    605
    606CONFIGFS_ATTR(target_fabric_port_, alua_tg_pt_gp);
    607CONFIGFS_ATTR(target_fabric_port_, alua_tg_pt_offline);
    608CONFIGFS_ATTR(target_fabric_port_, alua_tg_pt_status);
    609CONFIGFS_ATTR(target_fabric_port_, alua_tg_pt_write_md);
    610
    611static struct configfs_attribute *target_fabric_port_attrs[] = {
    612	&target_fabric_port_attr_alua_tg_pt_gp,
    613	&target_fabric_port_attr_alua_tg_pt_offline,
    614	&target_fabric_port_attr_alua_tg_pt_status,
    615	&target_fabric_port_attr_alua_tg_pt_write_md,
    616	NULL,
    617};
    618
    619static int target_fabric_port_link(
    620	struct config_item *lun_ci,
    621	struct config_item *se_dev_ci)
    622{
    623	struct config_item *tpg_ci;
    624	struct se_lun *lun = container_of(to_config_group(lun_ci),
    625				struct se_lun, lun_group);
    626	struct se_portal_group *se_tpg;
    627	struct se_device *dev;
    628	struct target_fabric_configfs *tf;
    629	int ret;
    630
    631	if (!se_dev_ci->ci_type ||
    632	    se_dev_ci->ci_type->ct_item_ops != &target_core_dev_item_ops) {
    633		pr_err("Bad se_dev_ci, not a valid se_dev_ci pointer: %p\n", se_dev_ci);
    634		return -EFAULT;
    635	}
    636	dev = container_of(to_config_group(se_dev_ci), struct se_device, dev_group);
    637
    638	if (!target_dev_configured(dev)) {
    639		pr_err("se_device not configured yet, cannot port link\n");
    640		return -ENODEV;
    641	}
    642
    643	tpg_ci = &lun_ci->ci_parent->ci_group->cg_item;
    644	se_tpg = container_of(to_config_group(tpg_ci),
    645				struct se_portal_group, tpg_group);
    646	tf = se_tpg->se_tpg_wwn->wwn_tf;
    647
    648	if (lun->lun_se_dev !=  NULL) {
    649		pr_err("Port Symlink already exists\n");
    650		return -EEXIST;
    651	}
    652
    653	ret = core_dev_add_lun(se_tpg, dev, lun);
    654	if (ret) {
    655		pr_err("core_dev_add_lun() failed: %d\n", ret);
    656		goto out;
    657	}
    658
    659	if (tf->tf_ops->fabric_post_link) {
    660		/*
    661		 * Call the optional fabric_post_link() to allow a
    662		 * fabric module to setup any additional state once
    663		 * core_dev_add_lun() has been called..
    664		 */
    665		tf->tf_ops->fabric_post_link(se_tpg, lun);
    666	}
    667
    668	return 0;
    669out:
    670	return ret;
    671}
    672
    673static void target_fabric_port_unlink(
    674	struct config_item *lun_ci,
    675	struct config_item *se_dev_ci)
    676{
    677	struct se_lun *lun = container_of(to_config_group(lun_ci),
    678				struct se_lun, lun_group);
    679	struct se_portal_group *se_tpg = lun->lun_tpg;
    680	struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
    681
    682	if (tf->tf_ops->fabric_pre_unlink) {
    683		/*
    684		 * Call the optional fabric_pre_unlink() to allow a
    685		 * fabric module to release any additional stat before
    686		 * core_dev_del_lun() is called.
    687		*/
    688		tf->tf_ops->fabric_pre_unlink(se_tpg, lun);
    689	}
    690
    691	core_dev_del_lun(se_tpg, lun);
    692}
    693
    694static void target_fabric_port_release(struct config_item *item)
    695{
    696	struct se_lun *lun = container_of(to_config_group(item),
    697					  struct se_lun, lun_group);
    698
    699	kfree_rcu(lun, rcu_head);
    700}
    701
    702static struct configfs_item_operations target_fabric_port_item_ops = {
    703	.release		= target_fabric_port_release,
    704	.allow_link		= target_fabric_port_link,
    705	.drop_link		= target_fabric_port_unlink,
    706};
    707
    708TF_CIT_SETUP(tpg_port, &target_fabric_port_item_ops, NULL, target_fabric_port_attrs);
    709
    710/* End of tfc_tpg_port_cit */
    711
    712/* Start of tfc_tpg_port_stat_cit */
    713
    714static struct config_group *target_core_port_stat_mkdir(
    715	struct config_group *group,
    716	const char *name)
    717{
    718	return ERR_PTR(-ENOSYS);
    719}
    720
    721static void target_core_port_stat_rmdir(
    722	struct config_group *group,
    723	struct config_item *item)
    724{
    725	return;
    726}
    727
    728static struct configfs_group_operations target_fabric_port_stat_group_ops = {
    729	.make_group		= target_core_port_stat_mkdir,
    730	.drop_item		= target_core_port_stat_rmdir,
    731};
    732
    733TF_CIT_SETUP(tpg_port_stat, NULL, &target_fabric_port_stat_group_ops, NULL);
    734
    735/* End of tfc_tpg_port_stat_cit */
    736
    737/* Start of tfc_tpg_lun_cit */
    738
    739static struct config_group *target_fabric_make_lun(
    740	struct config_group *group,
    741	const char *name)
    742{
    743	struct se_lun *lun;
    744	struct se_portal_group *se_tpg = container_of(group,
    745			struct se_portal_group, tpg_lun_group);
    746	struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
    747	unsigned long long unpacked_lun;
    748	int errno;
    749
    750	if (strstr(name, "lun_") != name) {
    751		pr_err("Unable to locate \'_\" in"
    752				" \"lun_$LUN_NUMBER\"\n");
    753		return ERR_PTR(-EINVAL);
    754	}
    755	errno = kstrtoull(name + 4, 0, &unpacked_lun);
    756	if (errno)
    757		return ERR_PTR(errno);
    758
    759	lun = core_tpg_alloc_lun(se_tpg, unpacked_lun);
    760	if (IS_ERR(lun))
    761		return ERR_CAST(lun);
    762
    763	config_group_init_type_name(&lun->lun_group, name,
    764			&tf->tf_tpg_port_cit);
    765
    766	config_group_init_type_name(&lun->port_stat_grps.stat_group,
    767			"statistics", &tf->tf_tpg_port_stat_cit);
    768	configfs_add_default_group(&lun->port_stat_grps.stat_group,
    769			&lun->lun_group);
    770
    771	target_stat_setup_port_default_groups(lun);
    772
    773	return &lun->lun_group;
    774}
    775
    776static void target_fabric_drop_lun(
    777	struct config_group *group,
    778	struct config_item *item)
    779{
    780	struct se_lun *lun = container_of(to_config_group(item),
    781				struct se_lun, lun_group);
    782
    783	configfs_remove_default_groups(&lun->port_stat_grps.stat_group);
    784	configfs_remove_default_groups(&lun->lun_group);
    785
    786	config_item_put(item);
    787}
    788
    789static struct configfs_group_operations target_fabric_lun_group_ops = {
    790	.make_group	= &target_fabric_make_lun,
    791	.drop_item	= &target_fabric_drop_lun,
    792};
    793
    794TF_CIT_SETUP(tpg_lun, NULL, &target_fabric_lun_group_ops, NULL);
    795
    796/* End of tfc_tpg_lun_cit */
    797
    798TF_CIT_SETUP_DRV(tpg_attrib, NULL, NULL);
    799TF_CIT_SETUP_DRV(tpg_auth, NULL, NULL);
    800TF_CIT_SETUP_DRV(tpg_param, NULL, NULL);
    801
    802/* Start of tfc_tpg_base_cit */
    803
    804static void target_fabric_tpg_release(struct config_item *item)
    805{
    806	struct se_portal_group *se_tpg = container_of(to_config_group(item),
    807			struct se_portal_group, tpg_group);
    808	struct se_wwn *wwn = se_tpg->se_tpg_wwn;
    809	struct target_fabric_configfs *tf = wwn->wwn_tf;
    810
    811	tf->tf_ops->fabric_drop_tpg(se_tpg);
    812}
    813
    814static struct configfs_item_operations target_fabric_tpg_base_item_ops = {
    815	.release		= target_fabric_tpg_release,
    816};
    817
    818static ssize_t target_fabric_tpg_base_enable_show(struct config_item *item,
    819						  char *page)
    820{
    821	return sysfs_emit(page, "%d\n", to_tpg(item)->enabled);
    822}
    823
    824static ssize_t target_fabric_tpg_base_enable_store(struct config_item *item,
    825						   const char *page,
    826						   size_t count)
    827{
    828	struct se_portal_group *se_tpg = to_tpg(item);
    829	int ret;
    830	bool op;
    831
    832	ret = strtobool(page, &op);
    833	if (ret)
    834		return ret;
    835
    836	if (se_tpg->enabled == op)
    837		return count;
    838
    839	ret = se_tpg->se_tpg_tfo->fabric_enable_tpg(se_tpg, op);
    840	if (ret)
    841		return ret;
    842
    843	se_tpg->enabled = op;
    844
    845	return count;
    846}
    847
    848CONFIGFS_ATTR(target_fabric_tpg_base_, enable);
    849
    850static int
    851target_fabric_setup_tpg_base_cit(struct target_fabric_configfs *tf)
    852{
    853	struct config_item_type *cit = &tf->tf_tpg_base_cit;
    854	struct configfs_attribute **attrs = NULL;
    855	size_t nr_attrs = 0;
    856	int i = 0;
    857
    858	if (tf->tf_ops->tfc_tpg_base_attrs)
    859		while (tf->tf_ops->tfc_tpg_base_attrs[nr_attrs] != NULL)
    860			nr_attrs++;
    861
    862	if (tf->tf_ops->fabric_enable_tpg)
    863		nr_attrs++;
    864
    865	if (nr_attrs == 0)
    866		goto done;
    867
    868	/* + 1 for final NULL in the array */
    869	attrs = kcalloc(nr_attrs + 1, sizeof(*attrs), GFP_KERNEL);
    870	if (!attrs)
    871		return -ENOMEM;
    872
    873	if (tf->tf_ops->tfc_tpg_base_attrs)
    874		for (; tf->tf_ops->tfc_tpg_base_attrs[i] != NULL; i++)
    875			attrs[i] = tf->tf_ops->tfc_tpg_base_attrs[i];
    876
    877	if (tf->tf_ops->fabric_enable_tpg)
    878		attrs[i] = &target_fabric_tpg_base_attr_enable;
    879
    880done:
    881	cit->ct_item_ops = &target_fabric_tpg_base_item_ops;
    882	cit->ct_attrs = attrs;
    883	cit->ct_owner = tf->tf_ops->module;
    884	pr_debug("Setup generic tpg_base\n");
    885
    886	return 0;
    887}
    888/* End of tfc_tpg_base_cit */
    889
    890/* Start of tfc_tpg_cit */
    891
    892static struct config_group *target_fabric_make_tpg(
    893	struct config_group *group,
    894	const char *name)
    895{
    896	struct se_wwn *wwn = container_of(group, struct se_wwn, wwn_group);
    897	struct target_fabric_configfs *tf = wwn->wwn_tf;
    898	struct se_portal_group *se_tpg;
    899
    900	if (!tf->tf_ops->fabric_make_tpg) {
    901		pr_err("tf->tf_ops->fabric_make_tpg is NULL\n");
    902		return ERR_PTR(-ENOSYS);
    903	}
    904
    905	se_tpg = tf->tf_ops->fabric_make_tpg(wwn, name);
    906	if (!se_tpg || IS_ERR(se_tpg))
    907		return ERR_PTR(-EINVAL);
    908
    909	config_group_init_type_name(&se_tpg->tpg_group, name,
    910			&tf->tf_tpg_base_cit);
    911
    912	config_group_init_type_name(&se_tpg->tpg_lun_group, "lun",
    913			&tf->tf_tpg_lun_cit);
    914	configfs_add_default_group(&se_tpg->tpg_lun_group,
    915			&se_tpg->tpg_group);
    916
    917	config_group_init_type_name(&se_tpg->tpg_np_group, "np",
    918			&tf->tf_tpg_np_cit);
    919	configfs_add_default_group(&se_tpg->tpg_np_group,
    920			&se_tpg->tpg_group);
    921
    922	config_group_init_type_name(&se_tpg->tpg_acl_group, "acls",
    923			&tf->tf_tpg_nacl_cit);
    924	configfs_add_default_group(&se_tpg->tpg_acl_group,
    925			&se_tpg->tpg_group);
    926
    927	config_group_init_type_name(&se_tpg->tpg_attrib_group, "attrib",
    928			&tf->tf_tpg_attrib_cit);
    929	configfs_add_default_group(&se_tpg->tpg_attrib_group,
    930			&se_tpg->tpg_group);
    931
    932	config_group_init_type_name(&se_tpg->tpg_auth_group, "auth",
    933			&tf->tf_tpg_auth_cit);
    934	configfs_add_default_group(&se_tpg->tpg_auth_group,
    935			&se_tpg->tpg_group);
    936
    937	config_group_init_type_name(&se_tpg->tpg_param_group, "param",
    938			&tf->tf_tpg_param_cit);
    939	configfs_add_default_group(&se_tpg->tpg_param_group,
    940			&se_tpg->tpg_group);
    941
    942	return &se_tpg->tpg_group;
    943}
    944
    945static void target_fabric_drop_tpg(
    946	struct config_group *group,
    947	struct config_item *item)
    948{
    949	struct se_portal_group *se_tpg = container_of(to_config_group(item),
    950				struct se_portal_group, tpg_group);
    951
    952	configfs_remove_default_groups(&se_tpg->tpg_group);
    953	config_item_put(item);
    954}
    955
    956static void target_fabric_release_wwn(struct config_item *item)
    957{
    958	struct se_wwn *wwn = container_of(to_config_group(item),
    959				struct se_wwn, wwn_group);
    960	struct target_fabric_configfs *tf = wwn->wwn_tf;
    961
    962	configfs_remove_default_groups(&wwn->fabric_stat_group);
    963	configfs_remove_default_groups(&wwn->param_group);
    964	tf->tf_ops->fabric_drop_wwn(wwn);
    965}
    966
    967static struct configfs_item_operations target_fabric_tpg_item_ops = {
    968	.release	= target_fabric_release_wwn,
    969};
    970
    971static struct configfs_group_operations target_fabric_tpg_group_ops = {
    972	.make_group	= target_fabric_make_tpg,
    973	.drop_item	= target_fabric_drop_tpg,
    974};
    975
    976TF_CIT_SETUP(tpg, &target_fabric_tpg_item_ops, &target_fabric_tpg_group_ops,
    977		NULL);
    978
    979/* End of tfc_tpg_cit */
    980
    981/* Start of tfc_wwn_fabric_stats_cit */
    982/*
    983 * This is used as a placeholder for struct se_wwn->fabric_stat_group
    984 * to allow fabrics access to ->fabric_stat_group->default_groups[]
    985 */
    986TF_CIT_SETUP(wwn_fabric_stats, NULL, NULL, NULL);
    987
    988/* End of tfc_wwn_fabric_stats_cit */
    989
    990static ssize_t
    991target_fabric_wwn_cmd_completion_affinity_show(struct config_item *item,
    992					       char *page)
    993{
    994	struct se_wwn *wwn = container_of(to_config_group(item), struct se_wwn,
    995					  param_group);
    996	return sprintf(page, "%d\n",
    997		       wwn->cmd_compl_affinity == WORK_CPU_UNBOUND ?
    998		       SE_COMPL_AFFINITY_CURR_CPU : wwn->cmd_compl_affinity);
    999}
   1000
   1001static ssize_t
   1002target_fabric_wwn_cmd_completion_affinity_store(struct config_item *item,
   1003						const char *page, size_t count)
   1004{
   1005	struct se_wwn *wwn = container_of(to_config_group(item), struct se_wwn,
   1006					  param_group);
   1007	int compl_val;
   1008
   1009	if (kstrtoint(page, 0, &compl_val))
   1010		return -EINVAL;
   1011
   1012	switch (compl_val) {
   1013	case SE_COMPL_AFFINITY_CPUID:
   1014		wwn->cmd_compl_affinity = compl_val;
   1015		break;
   1016	case SE_COMPL_AFFINITY_CURR_CPU:
   1017		wwn->cmd_compl_affinity = WORK_CPU_UNBOUND;
   1018		break;
   1019	default:
   1020		if (compl_val < 0 || compl_val >= nr_cpu_ids ||
   1021		    !cpu_online(compl_val)) {
   1022			pr_err("Command completion value must be between %d and %d or an online CPU.\n",
   1023			       SE_COMPL_AFFINITY_CPUID,
   1024			       SE_COMPL_AFFINITY_CURR_CPU);
   1025			return -EINVAL;
   1026		}
   1027		wwn->cmd_compl_affinity = compl_val;
   1028	}
   1029
   1030	return count;
   1031}
   1032CONFIGFS_ATTR(target_fabric_wwn_, cmd_completion_affinity);
   1033
   1034static struct configfs_attribute *target_fabric_wwn_param_attrs[] = {
   1035	&target_fabric_wwn_attr_cmd_completion_affinity,
   1036	NULL,
   1037};
   1038
   1039TF_CIT_SETUP(wwn_param, NULL, NULL, target_fabric_wwn_param_attrs);
   1040
   1041/* Start of tfc_wwn_cit */
   1042
   1043static struct config_group *target_fabric_make_wwn(
   1044	struct config_group *group,
   1045	const char *name)
   1046{
   1047	struct target_fabric_configfs *tf = container_of(group,
   1048				struct target_fabric_configfs, tf_group);
   1049	struct se_wwn *wwn;
   1050
   1051	if (!tf->tf_ops->fabric_make_wwn) {
   1052		pr_err("tf->tf_ops.fabric_make_wwn is NULL\n");
   1053		return ERR_PTR(-ENOSYS);
   1054	}
   1055
   1056	wwn = tf->tf_ops->fabric_make_wwn(tf, group, name);
   1057	if (!wwn || IS_ERR(wwn))
   1058		return ERR_PTR(-EINVAL);
   1059
   1060	wwn->cmd_compl_affinity = SE_COMPL_AFFINITY_CPUID;
   1061	wwn->wwn_tf = tf;
   1062
   1063	config_group_init_type_name(&wwn->wwn_group, name, &tf->tf_tpg_cit);
   1064
   1065	config_group_init_type_name(&wwn->fabric_stat_group, "fabric_statistics",
   1066			&tf->tf_wwn_fabric_stats_cit);
   1067	configfs_add_default_group(&wwn->fabric_stat_group, &wwn->wwn_group);
   1068
   1069	config_group_init_type_name(&wwn->param_group, "param",
   1070			&tf->tf_wwn_param_cit);
   1071	configfs_add_default_group(&wwn->param_group, &wwn->wwn_group);
   1072
   1073	if (tf->tf_ops->add_wwn_groups)
   1074		tf->tf_ops->add_wwn_groups(wwn);
   1075	return &wwn->wwn_group;
   1076}
   1077
   1078static void target_fabric_drop_wwn(
   1079	struct config_group *group,
   1080	struct config_item *item)
   1081{
   1082	struct se_wwn *wwn = container_of(to_config_group(item),
   1083				struct se_wwn, wwn_group);
   1084
   1085	configfs_remove_default_groups(&wwn->wwn_group);
   1086	config_item_put(item);
   1087}
   1088
   1089static struct configfs_group_operations target_fabric_wwn_group_ops = {
   1090	.make_group	= target_fabric_make_wwn,
   1091	.drop_item	= target_fabric_drop_wwn,
   1092};
   1093
   1094TF_CIT_SETUP_DRV(wwn, NULL, &target_fabric_wwn_group_ops);
   1095TF_CIT_SETUP_DRV(discovery, NULL, NULL);
   1096
   1097int target_fabric_setup_cits(struct target_fabric_configfs *tf)
   1098{
   1099	int ret;
   1100
   1101	target_fabric_setup_discovery_cit(tf);
   1102	target_fabric_setup_wwn_cit(tf);
   1103	target_fabric_setup_wwn_fabric_stats_cit(tf);
   1104	target_fabric_setup_wwn_param_cit(tf);
   1105	target_fabric_setup_tpg_cit(tf);
   1106
   1107	ret = target_fabric_setup_tpg_base_cit(tf);
   1108	if (ret)
   1109		return ret;
   1110
   1111	target_fabric_setup_tpg_port_cit(tf);
   1112	target_fabric_setup_tpg_port_stat_cit(tf);
   1113	target_fabric_setup_tpg_lun_cit(tf);
   1114	target_fabric_setup_tpg_np_cit(tf);
   1115	target_fabric_setup_tpg_np_base_cit(tf);
   1116	target_fabric_setup_tpg_attrib_cit(tf);
   1117	target_fabric_setup_tpg_auth_cit(tf);
   1118	target_fabric_setup_tpg_param_cit(tf);
   1119	target_fabric_setup_tpg_nacl_cit(tf);
   1120	target_fabric_setup_tpg_nacl_base_cit(tf);
   1121	target_fabric_setup_tpg_nacl_attrib_cit(tf);
   1122	target_fabric_setup_tpg_nacl_auth_cit(tf);
   1123	target_fabric_setup_tpg_nacl_param_cit(tf);
   1124	target_fabric_setup_tpg_nacl_stat_cit(tf);
   1125	target_fabric_setup_tpg_mappedlun_cit(tf);
   1126	target_fabric_setup_tpg_mappedlun_stat_cit(tf);
   1127
   1128	return 0;
   1129}