Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*******************************************************************************
0003 * Filename: target_core_fabric_configfs.c
0004  *
0005  * This file contains generic fabric module configfs infrastructure for
0006  * TCM v4.x code
0007  *
0008  * (c) Copyright 2010-2013 Datera, Inc.
0009  *
0010  * Nicholas A. Bellinger <nab@linux-iscsi.org>
0011 *
0012  ****************************************************************************/
0013 
0014 #include <linux/module.h>
0015 #include <linux/moduleparam.h>
0016 #include <linux/utsname.h>
0017 #include <linux/init.h>
0018 #include <linux/fs.h>
0019 #include <linux/namei.h>
0020 #include <linux/slab.h>
0021 #include <linux/types.h>
0022 #include <linux/delay.h>
0023 #include <linux/unistd.h>
0024 #include <linux/string.h>
0025 #include <linux/syscalls.h>
0026 #include <linux/configfs.h>
0027 
0028 #include <target/target_core_base.h>
0029 #include <target/target_core_backend.h>
0030 #include <target/target_core_fabric.h>
0031 
0032 #include "target_core_internal.h"
0033 #include "target_core_alua.h"
0034 #include "target_core_pr.h"
0035 
0036 #define TF_CIT_SETUP(_name, _item_ops, _group_ops, _attrs)      \
0037 static void target_fabric_setup_##_name##_cit(struct target_fabric_configfs *tf) \
0038 {                                   \
0039     struct config_item_type *cit = &tf->tf_##_name##_cit;       \
0040                                     \
0041     cit->ct_item_ops = _item_ops;                   \
0042     cit->ct_group_ops = _group_ops;                 \
0043     cit->ct_attrs = _attrs;                     \
0044     cit->ct_owner = tf->tf_ops->module;             \
0045     pr_debug("Setup generic %s\n", __stringify(_name));     \
0046 }
0047 
0048 #define TF_CIT_SETUP_DRV(_name, _item_ops, _group_ops)      \
0049 static void target_fabric_setup_##_name##_cit(struct target_fabric_configfs *tf) \
0050 {                                   \
0051     struct config_item_type *cit = &tf->tf_##_name##_cit;       \
0052     struct configfs_attribute **attrs = tf->tf_ops->tfc_##_name##_attrs; \
0053                                     \
0054     cit->ct_item_ops = _item_ops;                   \
0055     cit->ct_group_ops = _group_ops;                 \
0056     cit->ct_attrs = attrs;                      \
0057     cit->ct_owner = tf->tf_ops->module;             \
0058     pr_debug("Setup generic %s\n", __stringify(_name));     \
0059 }
0060 
0061 static struct configfs_item_operations target_fabric_port_item_ops;
0062 
0063 /* Start of tfc_tpg_mappedlun_cit */
0064 
0065 static int target_fabric_mappedlun_link(
0066     struct config_item *lun_acl_ci,
0067     struct config_item *lun_ci)
0068 {
0069     struct se_dev_entry *deve;
0070     struct se_lun *lun;
0071     struct se_lun_acl *lacl = container_of(to_config_group(lun_acl_ci),
0072             struct se_lun_acl, se_lun_group);
0073     struct se_portal_group *se_tpg;
0074     struct config_item *nacl_ci, *tpg_ci, *tpg_ci_s, *wwn_ci, *wwn_ci_s;
0075     bool lun_access_ro;
0076 
0077     if (!lun_ci->ci_type ||
0078         lun_ci->ci_type->ct_item_ops != &target_fabric_port_item_ops) {
0079         pr_err("Bad lun_ci, not a valid lun_ci pointer: %p\n", lun_ci);
0080         return -EFAULT;
0081     }
0082     lun = container_of(to_config_group(lun_ci), struct se_lun, lun_group);
0083 
0084     /*
0085      * Ensure that the source port exists
0086      */
0087     if (!lun->lun_se_dev) {
0088         pr_err("Source se_lun->lun_se_dev does not exist\n");
0089         return -EINVAL;
0090     }
0091     if (lun->lun_shutdown) {
0092         pr_err("Unable to create mappedlun symlink because"
0093             " lun->lun_shutdown=true\n");
0094         return -EINVAL;
0095     }
0096     se_tpg = lun->lun_tpg;
0097 
0098     nacl_ci = &lun_acl_ci->ci_parent->ci_group->cg_item;
0099     tpg_ci = &nacl_ci->ci_group->cg_item;
0100     wwn_ci = &tpg_ci->ci_group->cg_item;
0101     tpg_ci_s = &lun_ci->ci_parent->ci_group->cg_item;
0102     wwn_ci_s = &tpg_ci_s->ci_group->cg_item;
0103     /*
0104      * Make sure the SymLink is going to the same $FABRIC/$WWN/tpgt_$TPGT
0105      */
0106     if (strcmp(config_item_name(wwn_ci), config_item_name(wwn_ci_s))) {
0107         pr_err("Illegal Initiator ACL SymLink outside of %s\n",
0108             config_item_name(wwn_ci));
0109         return -EINVAL;
0110     }
0111     if (strcmp(config_item_name(tpg_ci), config_item_name(tpg_ci_s))) {
0112         pr_err("Illegal Initiator ACL Symlink outside of %s"
0113             " TPGT: %s\n", config_item_name(wwn_ci),
0114             config_item_name(tpg_ci));
0115         return -EINVAL;
0116     }
0117     /*
0118      * If this struct se_node_acl was dynamically generated with
0119      * tpg_1/attrib/generate_node_acls=1, use the existing
0120      * deve->lun_access_ro value, which will be true when
0121      * tpg_1/attrib/demo_mode_write_protect=1
0122      */
0123     rcu_read_lock();
0124     deve = target_nacl_find_deve(lacl->se_lun_nacl, lacl->mapped_lun);
0125     if (deve)
0126         lun_access_ro = deve->lun_access_ro;
0127     else
0128         lun_access_ro =
0129             (se_tpg->se_tpg_tfo->tpg_check_prod_mode_write_protect(
0130                 se_tpg)) ? true : false;
0131     rcu_read_unlock();
0132     /*
0133      * Determine the actual mapped LUN value user wants..
0134      *
0135      * This value is what the SCSI Initiator actually sees the
0136      * $FABRIC/$WWPN/$TPGT/lun/lun_* as on their SCSI Initiator Ports.
0137      */
0138     return core_dev_add_initiator_node_lun_acl(se_tpg, lacl, lun, lun_access_ro);
0139 }
0140 
0141 static void target_fabric_mappedlun_unlink(
0142     struct config_item *lun_acl_ci,
0143     struct config_item *lun_ci)
0144 {
0145     struct se_lun_acl *lacl = container_of(to_config_group(lun_acl_ci),
0146             struct se_lun_acl, se_lun_group);
0147     struct se_lun *lun = container_of(to_config_group(lun_ci),
0148             struct se_lun, lun_group);
0149 
0150     core_dev_del_initiator_node_lun_acl(lun, lacl);
0151 }
0152 
0153 static struct se_lun_acl *item_to_lun_acl(struct config_item *item)
0154 {
0155     return container_of(to_config_group(item), struct se_lun_acl,
0156             se_lun_group);
0157 }
0158 
0159 static ssize_t target_fabric_mappedlun_write_protect_show(
0160         struct config_item *item, char *page)
0161 {
0162     struct se_lun_acl *lacl = item_to_lun_acl(item);
0163     struct se_node_acl *se_nacl = lacl->se_lun_nacl;
0164     struct se_dev_entry *deve;
0165     ssize_t len = 0;
0166 
0167     rcu_read_lock();
0168     deve = target_nacl_find_deve(se_nacl, lacl->mapped_lun);
0169     if (deve) {
0170         len = sprintf(page, "%d\n", deve->lun_access_ro);
0171     }
0172     rcu_read_unlock();
0173 
0174     return len;
0175 }
0176 
0177 static ssize_t target_fabric_mappedlun_write_protect_store(
0178         struct config_item *item, const char *page, size_t count)
0179 {
0180     struct se_lun_acl *lacl = item_to_lun_acl(item);
0181     struct se_node_acl *se_nacl = lacl->se_lun_nacl;
0182     struct se_portal_group *se_tpg = se_nacl->se_tpg;
0183     unsigned long wp;
0184     int ret;
0185 
0186     ret = kstrtoul(page, 0, &wp);
0187     if (ret)
0188         return ret;
0189 
0190     if ((wp != 1) && (wp != 0))
0191         return -EINVAL;
0192 
0193     /* wp=1 means lun_access_ro=true */
0194     core_update_device_list_access(lacl->mapped_lun, wp, lacl->se_lun_nacl);
0195 
0196     pr_debug("%s_ConfigFS: Changed Initiator ACL: %s"
0197         " Mapped LUN: %llu Write Protect bit to %s\n",
0198         se_tpg->se_tpg_tfo->fabric_name,
0199         se_nacl->initiatorname, lacl->mapped_lun, (wp) ? "ON" : "OFF");
0200 
0201     return count;
0202 
0203 }
0204 
0205 CONFIGFS_ATTR(target_fabric_mappedlun_, write_protect);
0206 
0207 static struct configfs_attribute *target_fabric_mappedlun_attrs[] = {
0208     &target_fabric_mappedlun_attr_write_protect,
0209     NULL,
0210 };
0211 
0212 static void target_fabric_mappedlun_release(struct config_item *item)
0213 {
0214     struct se_lun_acl *lacl = container_of(to_config_group(item),
0215                 struct se_lun_acl, se_lun_group);
0216     struct se_portal_group *se_tpg = lacl->se_lun_nacl->se_tpg;
0217 
0218     core_dev_free_initiator_node_lun_acl(se_tpg, lacl);
0219 }
0220 
0221 static struct configfs_item_operations target_fabric_mappedlun_item_ops = {
0222     .release        = target_fabric_mappedlun_release,
0223     .allow_link     = target_fabric_mappedlun_link,
0224     .drop_link      = target_fabric_mappedlun_unlink,
0225 };
0226 
0227 TF_CIT_SETUP(tpg_mappedlun, &target_fabric_mappedlun_item_ops, NULL,
0228         target_fabric_mappedlun_attrs);
0229 
0230 /* End of tfc_tpg_mappedlun_cit */
0231 
0232 /* Start of tfc_tpg_mappedlun_port_cit */
0233 
0234 static struct config_group *target_core_mappedlun_stat_mkdir(
0235     struct config_group *group,
0236     const char *name)
0237 {
0238     return ERR_PTR(-ENOSYS);
0239 }
0240 
0241 static void target_core_mappedlun_stat_rmdir(
0242     struct config_group *group,
0243     struct config_item *item)
0244 {
0245     return;
0246 }
0247 
0248 static struct configfs_group_operations target_fabric_mappedlun_stat_group_ops = {
0249     .make_group     = target_core_mappedlun_stat_mkdir,
0250     .drop_item      = target_core_mappedlun_stat_rmdir,
0251 };
0252 
0253 TF_CIT_SETUP(tpg_mappedlun_stat, NULL, &target_fabric_mappedlun_stat_group_ops,
0254         NULL);
0255 
0256 /* End of tfc_tpg_mappedlun_port_cit */
0257 
0258 TF_CIT_SETUP_DRV(tpg_nacl_attrib, NULL, NULL);
0259 TF_CIT_SETUP_DRV(tpg_nacl_auth, NULL, NULL);
0260 TF_CIT_SETUP_DRV(tpg_nacl_param, NULL, NULL);
0261 
0262 /* Start of tfc_tpg_nacl_base_cit */
0263 
0264 static struct config_group *target_fabric_make_mappedlun(
0265     struct config_group *group,
0266     const char *name)
0267 {
0268     struct se_node_acl *se_nacl = container_of(group,
0269             struct se_node_acl, acl_group);
0270     struct se_portal_group *se_tpg = se_nacl->se_tpg;
0271     struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
0272     struct se_lun_acl *lacl = NULL;
0273     char *buf;
0274     unsigned long long mapped_lun;
0275     int ret = 0;
0276 
0277     buf = kzalloc(strlen(name) + 1, GFP_KERNEL);
0278     if (!buf) {
0279         pr_err("Unable to allocate memory for name buf\n");
0280         return ERR_PTR(-ENOMEM);
0281     }
0282     snprintf(buf, strlen(name) + 1, "%s", name);
0283     /*
0284      * Make sure user is creating iscsi/$IQN/$TPGT/acls/$INITIATOR/lun_$ID.
0285      */
0286     if (strstr(buf, "lun_") != buf) {
0287         pr_err("Unable to locate \"lun_\" from buf: %s"
0288             " name: %s\n", buf, name);
0289         ret = -EINVAL;
0290         goto out;
0291     }
0292     /*
0293      * Determine the Mapped LUN value.  This is what the SCSI Initiator
0294      * Port will actually see.
0295      */
0296     ret = kstrtoull(buf + 4, 0, &mapped_lun);
0297     if (ret)
0298         goto out;
0299 
0300     lacl = core_dev_init_initiator_node_lun_acl(se_tpg, se_nacl,
0301             mapped_lun, &ret);
0302     if (!lacl) {
0303         ret = -EINVAL;
0304         goto out;
0305     }
0306 
0307     config_group_init_type_name(&lacl->se_lun_group, name,
0308             &tf->tf_tpg_mappedlun_cit);
0309 
0310     config_group_init_type_name(&lacl->ml_stat_grps.stat_group,
0311             "statistics", &tf->tf_tpg_mappedlun_stat_cit);
0312     configfs_add_default_group(&lacl->ml_stat_grps.stat_group,
0313             &lacl->se_lun_group);
0314 
0315     target_stat_setup_mappedlun_default_groups(lacl);
0316 
0317     kfree(buf);
0318     return &lacl->se_lun_group;
0319 out:
0320     kfree(lacl);
0321     kfree(buf);
0322     return ERR_PTR(ret);
0323 }
0324 
0325 static void target_fabric_drop_mappedlun(
0326     struct config_group *group,
0327     struct config_item *item)
0328 {
0329     struct se_lun_acl *lacl = container_of(to_config_group(item),
0330             struct se_lun_acl, se_lun_group);
0331 
0332     configfs_remove_default_groups(&lacl->ml_stat_grps.stat_group);
0333     configfs_remove_default_groups(&lacl->se_lun_group);
0334 
0335     config_item_put(item);
0336 }
0337 
0338 static void target_fabric_nacl_base_release(struct config_item *item)
0339 {
0340     struct se_node_acl *se_nacl = container_of(to_config_group(item),
0341             struct se_node_acl, acl_group);
0342 
0343     configfs_remove_default_groups(&se_nacl->acl_fabric_stat_group);
0344     core_tpg_del_initiator_node_acl(se_nacl);
0345 }
0346 
0347 static struct configfs_item_operations target_fabric_nacl_base_item_ops = {
0348     .release        = target_fabric_nacl_base_release,
0349 };
0350 
0351 static struct configfs_group_operations target_fabric_nacl_base_group_ops = {
0352     .make_group     = target_fabric_make_mappedlun,
0353     .drop_item      = target_fabric_drop_mappedlun,
0354 };
0355 
0356 TF_CIT_SETUP_DRV(tpg_nacl_base, &target_fabric_nacl_base_item_ops,
0357         &target_fabric_nacl_base_group_ops);
0358 
0359 /* End of tfc_tpg_nacl_base_cit */
0360 
0361 /* Start of tfc_node_fabric_stats_cit */
0362 /*
0363  * This is used as a placeholder for struct se_node_acl->acl_fabric_stat_group
0364  * to allow fabrics access to ->acl_fabric_stat_group->default_groups[]
0365  */
0366 TF_CIT_SETUP(tpg_nacl_stat, NULL, NULL, NULL);
0367 
0368 /* End of tfc_wwn_fabric_stats_cit */
0369 
0370 /* Start of tfc_tpg_nacl_cit */
0371 
0372 static struct config_group *target_fabric_make_nodeacl(
0373     struct config_group *group,
0374     const char *name)
0375 {
0376     struct se_portal_group *se_tpg = container_of(group,
0377             struct se_portal_group, tpg_acl_group);
0378     struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
0379     struct se_node_acl *se_nacl;
0380 
0381     se_nacl = core_tpg_add_initiator_node_acl(se_tpg, name);
0382     if (IS_ERR(se_nacl))
0383         return ERR_CAST(se_nacl);
0384 
0385     config_group_init_type_name(&se_nacl->acl_group, name,
0386             &tf->tf_tpg_nacl_base_cit);
0387 
0388     config_group_init_type_name(&se_nacl->acl_attrib_group, "attrib",
0389             &tf->tf_tpg_nacl_attrib_cit);
0390     configfs_add_default_group(&se_nacl->acl_attrib_group,
0391             &se_nacl->acl_group);
0392 
0393     config_group_init_type_name(&se_nacl->acl_auth_group, "auth",
0394             &tf->tf_tpg_nacl_auth_cit);
0395     configfs_add_default_group(&se_nacl->acl_auth_group,
0396             &se_nacl->acl_group);
0397 
0398     config_group_init_type_name(&se_nacl->acl_param_group, "param",
0399             &tf->tf_tpg_nacl_param_cit);
0400     configfs_add_default_group(&se_nacl->acl_param_group,
0401             &se_nacl->acl_group);
0402 
0403     config_group_init_type_name(&se_nacl->acl_fabric_stat_group,
0404             "fabric_statistics", &tf->tf_tpg_nacl_stat_cit);
0405     configfs_add_default_group(&se_nacl->acl_fabric_stat_group,
0406             &se_nacl->acl_group);
0407 
0408     if (tf->tf_ops->fabric_init_nodeacl) {
0409         int ret = tf->tf_ops->fabric_init_nodeacl(se_nacl, name);
0410         if (ret) {
0411             configfs_remove_default_groups(&se_nacl->acl_fabric_stat_group);
0412             core_tpg_del_initiator_node_acl(se_nacl);
0413             return ERR_PTR(ret);
0414         }
0415     }
0416 
0417     return &se_nacl->acl_group;
0418 }
0419 
0420 static void target_fabric_drop_nodeacl(
0421     struct config_group *group,
0422     struct config_item *item)
0423 {
0424     struct se_node_acl *se_nacl = container_of(to_config_group(item),
0425             struct se_node_acl, acl_group);
0426 
0427     configfs_remove_default_groups(&se_nacl->acl_group);
0428 
0429     /*
0430      * struct se_node_acl free is done in target_fabric_nacl_base_release()
0431      */
0432     config_item_put(item);
0433 }
0434 
0435 static struct configfs_group_operations target_fabric_nacl_group_ops = {
0436     .make_group = target_fabric_make_nodeacl,
0437     .drop_item  = target_fabric_drop_nodeacl,
0438 };
0439 
0440 TF_CIT_SETUP(tpg_nacl, NULL, &target_fabric_nacl_group_ops, NULL);
0441 
0442 /* End of tfc_tpg_nacl_cit */
0443 
0444 /* Start of tfc_tpg_np_base_cit */
0445 
0446 static void target_fabric_np_base_release(struct config_item *item)
0447 {
0448     struct se_tpg_np *se_tpg_np = container_of(to_config_group(item),
0449                 struct se_tpg_np, tpg_np_group);
0450     struct se_portal_group *se_tpg = se_tpg_np->tpg_np_parent;
0451     struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
0452 
0453     tf->tf_ops->fabric_drop_np(se_tpg_np);
0454 }
0455 
0456 static struct configfs_item_operations target_fabric_np_base_item_ops = {
0457     .release        = target_fabric_np_base_release,
0458 };
0459 
0460 TF_CIT_SETUP_DRV(tpg_np_base, &target_fabric_np_base_item_ops, NULL);
0461 
0462 /* End of tfc_tpg_np_base_cit */
0463 
0464 /* Start of tfc_tpg_np_cit */
0465 
0466 static struct config_group *target_fabric_make_np(
0467     struct config_group *group,
0468     const char *name)
0469 {
0470     struct se_portal_group *se_tpg = container_of(group,
0471                 struct se_portal_group, tpg_np_group);
0472     struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
0473     struct se_tpg_np *se_tpg_np;
0474 
0475     if (!tf->tf_ops->fabric_make_np) {
0476         pr_err("tf->tf_ops.fabric_make_np is NULL\n");
0477         return ERR_PTR(-ENOSYS);
0478     }
0479 
0480     se_tpg_np = tf->tf_ops->fabric_make_np(se_tpg, group, name);
0481     if (!se_tpg_np || IS_ERR(se_tpg_np))
0482         return ERR_PTR(-EINVAL);
0483 
0484     se_tpg_np->tpg_np_parent = se_tpg;
0485     config_group_init_type_name(&se_tpg_np->tpg_np_group, name,
0486             &tf->tf_tpg_np_base_cit);
0487 
0488     return &se_tpg_np->tpg_np_group;
0489 }
0490 
0491 static void target_fabric_drop_np(
0492     struct config_group *group,
0493     struct config_item *item)
0494 {
0495     /*
0496      * struct se_tpg_np is released via target_fabric_np_base_release()
0497      */
0498     config_item_put(item);
0499 }
0500 
0501 static struct configfs_group_operations target_fabric_np_group_ops = {
0502     .make_group = &target_fabric_make_np,
0503     .drop_item  = &target_fabric_drop_np,
0504 };
0505 
0506 TF_CIT_SETUP(tpg_np, NULL, &target_fabric_np_group_ops, NULL);
0507 
0508 /* End of tfc_tpg_np_cit */
0509 
0510 /* Start of tfc_tpg_port_cit */
0511 
0512 static struct se_lun *item_to_lun(struct config_item *item)
0513 {
0514     return container_of(to_config_group(item), struct se_lun,
0515             lun_group);
0516 }
0517 
0518 static ssize_t target_fabric_port_alua_tg_pt_gp_show(struct config_item *item,
0519         char *page)
0520 {
0521     struct se_lun *lun = item_to_lun(item);
0522 
0523     if (!lun->lun_se_dev)
0524         return -ENODEV;
0525 
0526     return core_alua_show_tg_pt_gp_info(lun, page);
0527 }
0528 
0529 static ssize_t target_fabric_port_alua_tg_pt_gp_store(struct config_item *item,
0530         const char *page, size_t count)
0531 {
0532     struct se_lun *lun = item_to_lun(item);
0533 
0534     if (!lun->lun_se_dev)
0535         return -ENODEV;
0536 
0537     return core_alua_store_tg_pt_gp_info(lun, page, count);
0538 }
0539 
0540 static ssize_t target_fabric_port_alua_tg_pt_offline_show(
0541         struct config_item *item, char *page)
0542 {
0543     struct se_lun *lun = item_to_lun(item);
0544 
0545     if (!lun->lun_se_dev)
0546         return -ENODEV;
0547 
0548     return core_alua_show_offline_bit(lun, page);
0549 }
0550 
0551 static ssize_t target_fabric_port_alua_tg_pt_offline_store(
0552         struct config_item *item, const char *page, size_t count)
0553 {
0554     struct se_lun *lun = item_to_lun(item);
0555 
0556     if (!lun->lun_se_dev)
0557         return -ENODEV;
0558 
0559     return core_alua_store_offline_bit(lun, page, count);
0560 }
0561 
0562 static ssize_t target_fabric_port_alua_tg_pt_status_show(
0563         struct config_item *item, char *page)
0564 {
0565     struct se_lun *lun = item_to_lun(item);
0566 
0567     if (!lun->lun_se_dev)
0568         return -ENODEV;
0569 
0570     return core_alua_show_secondary_status(lun, page);
0571 }
0572 
0573 static ssize_t target_fabric_port_alua_tg_pt_status_store(
0574         struct config_item *item, const char *page, size_t count)
0575 {
0576     struct se_lun *lun = item_to_lun(item);
0577 
0578     if (!lun->lun_se_dev)
0579         return -ENODEV;
0580 
0581     return core_alua_store_secondary_status(lun, page, count);
0582 }
0583 
0584 static ssize_t target_fabric_port_alua_tg_pt_write_md_show(
0585         struct config_item *item, char *page)
0586 {
0587     struct se_lun *lun = item_to_lun(item);
0588 
0589     if (!lun->lun_se_dev)
0590         return -ENODEV;
0591 
0592     return core_alua_show_secondary_write_metadata(lun, page);
0593 }
0594 
0595 static ssize_t target_fabric_port_alua_tg_pt_write_md_store(
0596         struct config_item *item, const char *page, size_t count)
0597 {
0598     struct se_lun *lun = item_to_lun(item);
0599 
0600     if (!lun->lun_se_dev)
0601         return -ENODEV;
0602 
0603     return core_alua_store_secondary_write_metadata(lun, page, count);
0604 }
0605 
0606 CONFIGFS_ATTR(target_fabric_port_, alua_tg_pt_gp);
0607 CONFIGFS_ATTR(target_fabric_port_, alua_tg_pt_offline);
0608 CONFIGFS_ATTR(target_fabric_port_, alua_tg_pt_status);
0609 CONFIGFS_ATTR(target_fabric_port_, alua_tg_pt_write_md);
0610 
0611 static struct configfs_attribute *target_fabric_port_attrs[] = {
0612     &target_fabric_port_attr_alua_tg_pt_gp,
0613     &target_fabric_port_attr_alua_tg_pt_offline,
0614     &target_fabric_port_attr_alua_tg_pt_status,
0615     &target_fabric_port_attr_alua_tg_pt_write_md,
0616     NULL,
0617 };
0618 
0619 static int target_fabric_port_link(
0620     struct config_item *lun_ci,
0621     struct config_item *se_dev_ci)
0622 {
0623     struct config_item *tpg_ci;
0624     struct se_lun *lun = container_of(to_config_group(lun_ci),
0625                 struct se_lun, lun_group);
0626     struct se_portal_group *se_tpg;
0627     struct se_device *dev;
0628     struct target_fabric_configfs *tf;
0629     int ret;
0630 
0631     if (!se_dev_ci->ci_type ||
0632         se_dev_ci->ci_type->ct_item_ops != &target_core_dev_item_ops) {
0633         pr_err("Bad se_dev_ci, not a valid se_dev_ci pointer: %p\n", se_dev_ci);
0634         return -EFAULT;
0635     }
0636     dev = container_of(to_config_group(se_dev_ci), struct se_device, dev_group);
0637 
0638     if (!target_dev_configured(dev)) {
0639         pr_err("se_device not configured yet, cannot port link\n");
0640         return -ENODEV;
0641     }
0642 
0643     tpg_ci = &lun_ci->ci_parent->ci_group->cg_item;
0644     se_tpg = container_of(to_config_group(tpg_ci),
0645                 struct se_portal_group, tpg_group);
0646     tf = se_tpg->se_tpg_wwn->wwn_tf;
0647 
0648     if (lun->lun_se_dev !=  NULL) {
0649         pr_err("Port Symlink already exists\n");
0650         return -EEXIST;
0651     }
0652 
0653     ret = core_dev_add_lun(se_tpg, dev, lun);
0654     if (ret) {
0655         pr_err("core_dev_add_lun() failed: %d\n", ret);
0656         goto out;
0657     }
0658 
0659     if (tf->tf_ops->fabric_post_link) {
0660         /*
0661          * Call the optional fabric_post_link() to allow a
0662          * fabric module to setup any additional state once
0663          * core_dev_add_lun() has been called..
0664          */
0665         tf->tf_ops->fabric_post_link(se_tpg, lun);
0666     }
0667 
0668     return 0;
0669 out:
0670     return ret;
0671 }
0672 
0673 static void target_fabric_port_unlink(
0674     struct config_item *lun_ci,
0675     struct config_item *se_dev_ci)
0676 {
0677     struct se_lun *lun = container_of(to_config_group(lun_ci),
0678                 struct se_lun, lun_group);
0679     struct se_portal_group *se_tpg = lun->lun_tpg;
0680     struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
0681 
0682     if (tf->tf_ops->fabric_pre_unlink) {
0683         /*
0684          * Call the optional fabric_pre_unlink() to allow a
0685          * fabric module to release any additional stat before
0686          * core_dev_del_lun() is called.
0687         */
0688         tf->tf_ops->fabric_pre_unlink(se_tpg, lun);
0689     }
0690 
0691     core_dev_del_lun(se_tpg, lun);
0692 }
0693 
0694 static void target_fabric_port_release(struct config_item *item)
0695 {
0696     struct se_lun *lun = container_of(to_config_group(item),
0697                       struct se_lun, lun_group);
0698 
0699     kfree_rcu(lun, rcu_head);
0700 }
0701 
0702 static struct configfs_item_operations target_fabric_port_item_ops = {
0703     .release        = target_fabric_port_release,
0704     .allow_link     = target_fabric_port_link,
0705     .drop_link      = target_fabric_port_unlink,
0706 };
0707 
0708 TF_CIT_SETUP(tpg_port, &target_fabric_port_item_ops, NULL, target_fabric_port_attrs);
0709 
0710 /* End of tfc_tpg_port_cit */
0711 
0712 /* Start of tfc_tpg_port_stat_cit */
0713 
0714 static struct config_group *target_core_port_stat_mkdir(
0715     struct config_group *group,
0716     const char *name)
0717 {
0718     return ERR_PTR(-ENOSYS);
0719 }
0720 
0721 static void target_core_port_stat_rmdir(
0722     struct config_group *group,
0723     struct config_item *item)
0724 {
0725     return;
0726 }
0727 
0728 static struct configfs_group_operations target_fabric_port_stat_group_ops = {
0729     .make_group     = target_core_port_stat_mkdir,
0730     .drop_item      = target_core_port_stat_rmdir,
0731 };
0732 
0733 TF_CIT_SETUP(tpg_port_stat, NULL, &target_fabric_port_stat_group_ops, NULL);
0734 
0735 /* End of tfc_tpg_port_stat_cit */
0736 
0737 /* Start of tfc_tpg_lun_cit */
0738 
0739 static struct config_group *target_fabric_make_lun(
0740     struct config_group *group,
0741     const char *name)
0742 {
0743     struct se_lun *lun;
0744     struct se_portal_group *se_tpg = container_of(group,
0745             struct se_portal_group, tpg_lun_group);
0746     struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
0747     unsigned long long unpacked_lun;
0748     int errno;
0749 
0750     if (strstr(name, "lun_") != name) {
0751         pr_err("Unable to locate \'_\" in"
0752                 " \"lun_$LUN_NUMBER\"\n");
0753         return ERR_PTR(-EINVAL);
0754     }
0755     errno = kstrtoull(name + 4, 0, &unpacked_lun);
0756     if (errno)
0757         return ERR_PTR(errno);
0758 
0759     lun = core_tpg_alloc_lun(se_tpg, unpacked_lun);
0760     if (IS_ERR(lun))
0761         return ERR_CAST(lun);
0762 
0763     config_group_init_type_name(&lun->lun_group, name,
0764             &tf->tf_tpg_port_cit);
0765 
0766     config_group_init_type_name(&lun->port_stat_grps.stat_group,
0767             "statistics", &tf->tf_tpg_port_stat_cit);
0768     configfs_add_default_group(&lun->port_stat_grps.stat_group,
0769             &lun->lun_group);
0770 
0771     target_stat_setup_port_default_groups(lun);
0772 
0773     return &lun->lun_group;
0774 }
0775 
0776 static void target_fabric_drop_lun(
0777     struct config_group *group,
0778     struct config_item *item)
0779 {
0780     struct se_lun *lun = container_of(to_config_group(item),
0781                 struct se_lun, lun_group);
0782 
0783     configfs_remove_default_groups(&lun->port_stat_grps.stat_group);
0784     configfs_remove_default_groups(&lun->lun_group);
0785 
0786     config_item_put(item);
0787 }
0788 
0789 static struct configfs_group_operations target_fabric_lun_group_ops = {
0790     .make_group = &target_fabric_make_lun,
0791     .drop_item  = &target_fabric_drop_lun,
0792 };
0793 
0794 TF_CIT_SETUP(tpg_lun, NULL, &target_fabric_lun_group_ops, NULL);
0795 
0796 /* End of tfc_tpg_lun_cit */
0797 
0798 TF_CIT_SETUP_DRV(tpg_attrib, NULL, NULL);
0799 TF_CIT_SETUP_DRV(tpg_auth, NULL, NULL);
0800 TF_CIT_SETUP_DRV(tpg_param, NULL, NULL);
0801 
0802 /* Start of tfc_tpg_base_cit */
0803 
0804 static void target_fabric_tpg_release(struct config_item *item)
0805 {
0806     struct se_portal_group *se_tpg = container_of(to_config_group(item),
0807             struct se_portal_group, tpg_group);
0808     struct se_wwn *wwn = se_tpg->se_tpg_wwn;
0809     struct target_fabric_configfs *tf = wwn->wwn_tf;
0810 
0811     tf->tf_ops->fabric_drop_tpg(se_tpg);
0812 }
0813 
0814 static struct configfs_item_operations target_fabric_tpg_base_item_ops = {
0815     .release        = target_fabric_tpg_release,
0816 };
0817 
0818 static ssize_t target_fabric_tpg_base_enable_show(struct config_item *item,
0819                           char *page)
0820 {
0821     return sysfs_emit(page, "%d\n", to_tpg(item)->enabled);
0822 }
0823 
0824 static ssize_t target_fabric_tpg_base_enable_store(struct config_item *item,
0825                            const char *page,
0826                            size_t count)
0827 {
0828     struct se_portal_group *se_tpg = to_tpg(item);
0829     int ret;
0830     bool op;
0831 
0832     ret = strtobool(page, &op);
0833     if (ret)
0834         return ret;
0835 
0836     if (se_tpg->enabled == op)
0837         return count;
0838 
0839     ret = se_tpg->se_tpg_tfo->fabric_enable_tpg(se_tpg, op);
0840     if (ret)
0841         return ret;
0842 
0843     se_tpg->enabled = op;
0844 
0845     return count;
0846 }
0847 
0848 CONFIGFS_ATTR(target_fabric_tpg_base_, enable);
0849 
0850 static int
0851 target_fabric_setup_tpg_base_cit(struct target_fabric_configfs *tf)
0852 {
0853     struct config_item_type *cit = &tf->tf_tpg_base_cit;
0854     struct configfs_attribute **attrs = NULL;
0855     size_t nr_attrs = 0;
0856     int i = 0;
0857 
0858     if (tf->tf_ops->tfc_tpg_base_attrs)
0859         while (tf->tf_ops->tfc_tpg_base_attrs[nr_attrs] != NULL)
0860             nr_attrs++;
0861 
0862     if (tf->tf_ops->fabric_enable_tpg)
0863         nr_attrs++;
0864 
0865     if (nr_attrs == 0)
0866         goto done;
0867 
0868     /* + 1 for final NULL in the array */
0869     attrs = kcalloc(nr_attrs + 1, sizeof(*attrs), GFP_KERNEL);
0870     if (!attrs)
0871         return -ENOMEM;
0872 
0873     if (tf->tf_ops->tfc_tpg_base_attrs)
0874         for (; tf->tf_ops->tfc_tpg_base_attrs[i] != NULL; i++)
0875             attrs[i] = tf->tf_ops->tfc_tpg_base_attrs[i];
0876 
0877     if (tf->tf_ops->fabric_enable_tpg)
0878         attrs[i] = &target_fabric_tpg_base_attr_enable;
0879 
0880 done:
0881     cit->ct_item_ops = &target_fabric_tpg_base_item_ops;
0882     cit->ct_attrs = attrs;
0883     cit->ct_owner = tf->tf_ops->module;
0884     pr_debug("Setup generic tpg_base\n");
0885 
0886     return 0;
0887 }
0888 /* End of tfc_tpg_base_cit */
0889 
0890 /* Start of tfc_tpg_cit */
0891 
0892 static struct config_group *target_fabric_make_tpg(
0893     struct config_group *group,
0894     const char *name)
0895 {
0896     struct se_wwn *wwn = container_of(group, struct se_wwn, wwn_group);
0897     struct target_fabric_configfs *tf = wwn->wwn_tf;
0898     struct se_portal_group *se_tpg;
0899 
0900     if (!tf->tf_ops->fabric_make_tpg) {
0901         pr_err("tf->tf_ops->fabric_make_tpg is NULL\n");
0902         return ERR_PTR(-ENOSYS);
0903     }
0904 
0905     se_tpg = tf->tf_ops->fabric_make_tpg(wwn, name);
0906     if (!se_tpg || IS_ERR(se_tpg))
0907         return ERR_PTR(-EINVAL);
0908 
0909     config_group_init_type_name(&se_tpg->tpg_group, name,
0910             &tf->tf_tpg_base_cit);
0911 
0912     config_group_init_type_name(&se_tpg->tpg_lun_group, "lun",
0913             &tf->tf_tpg_lun_cit);
0914     configfs_add_default_group(&se_tpg->tpg_lun_group,
0915             &se_tpg->tpg_group);
0916 
0917     config_group_init_type_name(&se_tpg->tpg_np_group, "np",
0918             &tf->tf_tpg_np_cit);
0919     configfs_add_default_group(&se_tpg->tpg_np_group,
0920             &se_tpg->tpg_group);
0921 
0922     config_group_init_type_name(&se_tpg->tpg_acl_group, "acls",
0923             &tf->tf_tpg_nacl_cit);
0924     configfs_add_default_group(&se_tpg->tpg_acl_group,
0925             &se_tpg->tpg_group);
0926 
0927     config_group_init_type_name(&se_tpg->tpg_attrib_group, "attrib",
0928             &tf->tf_tpg_attrib_cit);
0929     configfs_add_default_group(&se_tpg->tpg_attrib_group,
0930             &se_tpg->tpg_group);
0931 
0932     config_group_init_type_name(&se_tpg->tpg_auth_group, "auth",
0933             &tf->tf_tpg_auth_cit);
0934     configfs_add_default_group(&se_tpg->tpg_auth_group,
0935             &se_tpg->tpg_group);
0936 
0937     config_group_init_type_name(&se_tpg->tpg_param_group, "param",
0938             &tf->tf_tpg_param_cit);
0939     configfs_add_default_group(&se_tpg->tpg_param_group,
0940             &se_tpg->tpg_group);
0941 
0942     return &se_tpg->tpg_group;
0943 }
0944 
0945 static void target_fabric_drop_tpg(
0946     struct config_group *group,
0947     struct config_item *item)
0948 {
0949     struct se_portal_group *se_tpg = container_of(to_config_group(item),
0950                 struct se_portal_group, tpg_group);
0951 
0952     configfs_remove_default_groups(&se_tpg->tpg_group);
0953     config_item_put(item);
0954 }
0955 
0956 static void target_fabric_release_wwn(struct config_item *item)
0957 {
0958     struct se_wwn *wwn = container_of(to_config_group(item),
0959                 struct se_wwn, wwn_group);
0960     struct target_fabric_configfs *tf = wwn->wwn_tf;
0961 
0962     configfs_remove_default_groups(&wwn->fabric_stat_group);
0963     configfs_remove_default_groups(&wwn->param_group);
0964     tf->tf_ops->fabric_drop_wwn(wwn);
0965 }
0966 
0967 static struct configfs_item_operations target_fabric_tpg_item_ops = {
0968     .release    = target_fabric_release_wwn,
0969 };
0970 
0971 static struct configfs_group_operations target_fabric_tpg_group_ops = {
0972     .make_group = target_fabric_make_tpg,
0973     .drop_item  = target_fabric_drop_tpg,
0974 };
0975 
0976 TF_CIT_SETUP(tpg, &target_fabric_tpg_item_ops, &target_fabric_tpg_group_ops,
0977         NULL);
0978 
0979 /* End of tfc_tpg_cit */
0980 
0981 /* Start of tfc_wwn_fabric_stats_cit */
0982 /*
0983  * This is used as a placeholder for struct se_wwn->fabric_stat_group
0984  * to allow fabrics access to ->fabric_stat_group->default_groups[]
0985  */
0986 TF_CIT_SETUP(wwn_fabric_stats, NULL, NULL, NULL);
0987 
0988 /* End of tfc_wwn_fabric_stats_cit */
0989 
0990 static ssize_t
0991 target_fabric_wwn_cmd_completion_affinity_show(struct config_item *item,
0992                            char *page)
0993 {
0994     struct se_wwn *wwn = container_of(to_config_group(item), struct se_wwn,
0995                       param_group);
0996     return sprintf(page, "%d\n",
0997                wwn->cmd_compl_affinity == WORK_CPU_UNBOUND ?
0998                SE_COMPL_AFFINITY_CURR_CPU : wwn->cmd_compl_affinity);
0999 }
1000 
1001 static ssize_t
1002 target_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 }
1032 CONFIGFS_ATTR(target_fabric_wwn_, cmd_completion_affinity);
1033 
1034 static struct configfs_attribute *target_fabric_wwn_param_attrs[] = {
1035     &target_fabric_wwn_attr_cmd_completion_affinity,
1036     NULL,
1037 };
1038 
1039 TF_CIT_SETUP(wwn_param, NULL, NULL, target_fabric_wwn_param_attrs);
1040 
1041 /* Start of tfc_wwn_cit */
1042 
1043 static 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 
1078 static 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 
1089 static 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 
1094 TF_CIT_SETUP_DRV(wwn, NULL, &target_fabric_wwn_group_ops);
1095 TF_CIT_SETUP_DRV(discovery, NULL, NULL);
1096 
1097 int 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 }