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