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-2012 RisingTide Systems LLC.
   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#include <target/target_core_fabric_configfs.h>
  39#include <target/target_core_configfs.h>
  40#include <target/configfs_macros.h>
  41
  42#include "target_core_internal.h"
  43#include "target_core_alua.h"
  44#include "target_core_pr.h"
  45
  46#define TF_CIT_SETUP(_name, _item_ops, _group_ops, _attrs)              \
  47static void target_fabric_setup_##_name##_cit(struct target_fabric_configfs *tf) \
  48{                                                                       \
  49        struct target_fabric_configfs_template *tfc = &tf->tf_cit_tmpl; \
  50        struct config_item_type *cit = &tfc->tfc_##_name##_cit;         \
  51                                                                        \
  52        cit->ct_item_ops = _item_ops;                                   \
  53        cit->ct_group_ops = _group_ops;                                 \
  54        cit->ct_attrs = _attrs;                                         \
  55        cit->ct_owner = tf->tf_module;                                  \
  56        pr_debug("Setup generic %s\n", __stringify(_name));             \
  57}
  58
  59/* Start of tfc_tpg_mappedlun_cit */
  60
  61static int target_fabric_mappedlun_link(
  62        struct config_item *lun_acl_ci,
  63        struct config_item *lun_ci)
  64{
  65        struct se_dev_entry *deve;
  66        struct se_lun *lun = container_of(to_config_group(lun_ci),
  67                        struct se_lun, lun_group);
  68        struct se_lun_acl *lacl = container_of(to_config_group(lun_acl_ci),
  69                        struct se_lun_acl, se_lun_group);
  70        struct se_portal_group *se_tpg;
  71        struct config_item *nacl_ci, *tpg_ci, *tpg_ci_s, *wwn_ci, *wwn_ci_s;
  72        int ret = 0, lun_access;
  73
  74        if (lun->lun_link_magic != SE_LUN_LINK_MAGIC) {
  75                pr_err("Bad lun->lun_link_magic, not a valid lun_ci pointer:"
  76                        " %p to struct lun: %p\n", lun_ci, lun);
  77                return -EFAULT;
  78        }
  79        /*
  80         * Ensure that the source port exists
  81         */
  82        if (!lun->lun_sep || !lun->lun_sep->sep_tpg) {
  83                pr_err("Source se_lun->lun_sep or lun->lun_sep->sep"
  84                                "_tpg does not exist\n");
  85                return -EINVAL;
  86        }
  87        se_tpg = lun->lun_sep->sep_tpg;
  88
  89        nacl_ci = &lun_acl_ci->ci_parent->ci_group->cg_item;
  90        tpg_ci = &nacl_ci->ci_group->cg_item;
  91        wwn_ci = &tpg_ci->ci_group->cg_item;
  92        tpg_ci_s = &lun_ci->ci_parent->ci_group->cg_item;
  93        wwn_ci_s = &tpg_ci_s->ci_group->cg_item;
  94        /*
  95         * Make sure the SymLink is going to the same $FABRIC/$WWN/tpgt_$TPGT
  96         */
  97        if (strcmp(config_item_name(wwn_ci), config_item_name(wwn_ci_s))) {
  98                pr_err("Illegal Initiator ACL SymLink outside of %s\n",
  99                        config_item_name(wwn_ci));
 100                return -EINVAL;
 101        }
 102        if (strcmp(config_item_name(tpg_ci), config_item_name(tpg_ci_s))) {
 103                pr_err("Illegal Initiator ACL Symlink outside of %s"
 104                        " TPGT: %s\n", config_item_name(wwn_ci),
 105                        config_item_name(tpg_ci));
 106                return -EINVAL;
 107        }
 108        /*
 109         * If this struct se_node_acl was dynamically generated with
 110         * tpg_1/attrib/generate_node_acls=1, use the existing deve->lun_flags,
 111         * which be will write protected (READ-ONLY) when
 112         * tpg_1/attrib/demo_mode_write_protect=1
 113         */
 114        spin_lock_irq(&lacl->se_lun_nacl->device_list_lock);
 115        deve = lacl->se_lun_nacl->device_list[lacl->mapped_lun];
 116        if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS)
 117                lun_access = deve->lun_flags;
 118        else
 119                lun_access =
 120                        (se_tpg->se_tpg_tfo->tpg_check_prod_mode_write_protect(
 121                                se_tpg)) ? TRANSPORT_LUNFLAGS_READ_ONLY :
 122                                           TRANSPORT_LUNFLAGS_READ_WRITE;
 123        spin_unlock_irq(&lacl->se_lun_nacl->device_list_lock);
 124        /*
 125         * Determine the actual mapped LUN value user wants..
 126         *
 127         * This value is what the SCSI Initiator actually sees the
 128         * iscsi/$IQN/$TPGT/lun/lun_* as on their SCSI Initiator Ports.
 129         */
 130        ret = core_dev_add_initiator_node_lun_acl(se_tpg, lacl,
 131                        lun->unpacked_lun, lun_access);
 132
 133        return (ret < 0) ? -EINVAL : 0;
 134}
 135
 136static int target_fabric_mappedlun_unlink(
 137        struct config_item *lun_acl_ci,
 138        struct config_item *lun_ci)
 139{
 140        struct se_lun *lun;
 141        struct se_lun_acl *lacl = container_of(to_config_group(lun_acl_ci),
 142                        struct se_lun_acl, se_lun_group);
 143        struct se_node_acl *nacl = lacl->se_lun_nacl;
 144        struct se_dev_entry *deve = nacl->device_list[lacl->mapped_lun];
 145        struct se_portal_group *se_tpg;
 146        /*
 147         * Determine if the underlying MappedLUN has already been released..
 148         */
 149        if (!deve->se_lun)
 150                return 0;
 151
 152        lun = container_of(to_config_group(lun_ci), struct se_lun, lun_group);
 153        se_tpg = lun->lun_sep->sep_tpg;
 154
 155        core_dev_del_initiator_node_lun_acl(se_tpg, lun, lacl);
 156        return 0;
 157}
 158
 159CONFIGFS_EATTR_STRUCT(target_fabric_mappedlun, se_lun_acl);
 160#define TCM_MAPPEDLUN_ATTR(_name, _mode)                                \
 161static struct target_fabric_mappedlun_attribute target_fabric_mappedlun_##_name = \
 162        __CONFIGFS_EATTR(_name, _mode,                                  \
 163        target_fabric_mappedlun_show_##_name,                           \
 164        target_fabric_mappedlun_store_##_name);
 165
 166static ssize_t target_fabric_mappedlun_show_write_protect(
 167        struct se_lun_acl *lacl,
 168        char *page)
 169{
 170        struct se_node_acl *se_nacl = lacl->se_lun_nacl;
 171        struct se_dev_entry *deve;
 172        ssize_t len;
 173
 174        spin_lock_irq(&se_nacl->device_list_lock);
 175        deve = se_nacl->device_list[lacl->mapped_lun];
 176        len = sprintf(page, "%d\n",
 177                        (deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY) ?
 178                        1 : 0);
 179        spin_unlock_irq(&se_nacl->device_list_lock);
 180
 181        return len;
 182}
 183
 184static ssize_t target_fabric_mappedlun_store_write_protect(
 185        struct se_lun_acl *lacl,
 186        const char *page,
 187        size_t count)
 188{
 189        struct se_node_acl *se_nacl = lacl->se_lun_nacl;
 190        struct se_portal_group *se_tpg = se_nacl->se_tpg;
 191        unsigned long op;
 192
 193        if (strict_strtoul(page, 0, &op))
 194                return -EINVAL;
 195
 196        if ((op != 1) && (op != 0))
 197                return -EINVAL;
 198
 199        core_update_device_list_access(lacl->mapped_lun, (op) ?
 200                        TRANSPORT_LUNFLAGS_READ_ONLY :
 201                        TRANSPORT_LUNFLAGS_READ_WRITE,
 202                        lacl->se_lun_nacl);
 203
 204        pr_debug("%s_ConfigFS: Changed Initiator ACL: %s"
 205                " Mapped LUN: %u Write Protect bit to %s\n",
 206                se_tpg->se_tpg_tfo->get_fabric_name(),
 207                lacl->initiatorname, lacl->mapped_lun, (op) ? "ON" : "OFF");
 208
 209        return count;
 210
 211}
 212
 213TCM_MAPPEDLUN_ATTR(write_protect, S_IRUGO | S_IWUSR);
 214
 215CONFIGFS_EATTR_OPS(target_fabric_mappedlun, se_lun_acl, se_lun_group);
 216
 217static void target_fabric_mappedlun_release(struct config_item *item)
 218{
 219        struct se_lun_acl *lacl = container_of(to_config_group(item),
 220                                struct se_lun_acl, se_lun_group);
 221        struct se_portal_group *se_tpg = lacl->se_lun_nacl->se_tpg;
 222
 223        core_dev_free_initiator_node_lun_acl(se_tpg, lacl);
 224}
 225
 226static struct configfs_attribute *target_fabric_mappedlun_attrs[] = {
 227        &target_fabric_mappedlun_write_protect.attr,
 228        NULL,
 229};
 230
 231static struct configfs_item_operations target_fabric_mappedlun_item_ops = {
 232        .release                = target_fabric_mappedlun_release,
 233        .show_attribute         = target_fabric_mappedlun_attr_show,
 234        .store_attribute        = target_fabric_mappedlun_attr_store,
 235        .allow_link             = target_fabric_mappedlun_link,
 236        .drop_link              = target_fabric_mappedlun_unlink,
 237};
 238
 239TF_CIT_SETUP(tpg_mappedlun, &target_fabric_mappedlun_item_ops, NULL,
 240                target_fabric_mappedlun_attrs);
 241
 242/* End of tfc_tpg_mappedlun_cit */
 243
 244/* Start of tfc_tpg_mappedlun_port_cit */
 245
 246static struct config_group *target_core_mappedlun_stat_mkdir(
 247        struct config_group *group,
 248        const char *name)
 249{
 250        return ERR_PTR(-ENOSYS);
 251}
 252
 253static void target_core_mappedlun_stat_rmdir(
 254        struct config_group *group,
 255        struct config_item *item)
 256{
 257        return;
 258}
 259
 260static struct configfs_group_operations target_fabric_mappedlun_stat_group_ops = {
 261        .make_group             = target_core_mappedlun_stat_mkdir,
 262        .drop_item              = target_core_mappedlun_stat_rmdir,
 263};
 264
 265TF_CIT_SETUP(tpg_mappedlun_stat, NULL, &target_fabric_mappedlun_stat_group_ops,
 266                NULL);
 267
 268/* End of tfc_tpg_mappedlun_port_cit */
 269
 270/* Start of tfc_tpg_nacl_attrib_cit */
 271
 272CONFIGFS_EATTR_OPS(target_fabric_nacl_attrib, se_node_acl, acl_attrib_group);
 273
 274static struct configfs_item_operations target_fabric_nacl_attrib_item_ops = {
 275        .show_attribute         = target_fabric_nacl_attrib_attr_show,
 276        .store_attribute        = target_fabric_nacl_attrib_attr_store,
 277};
 278
 279TF_CIT_SETUP(tpg_nacl_attrib, &target_fabric_nacl_attrib_item_ops, NULL, NULL);
 280
 281/* End of tfc_tpg_nacl_attrib_cit */
 282
 283/* Start of tfc_tpg_nacl_auth_cit */
 284
 285CONFIGFS_EATTR_OPS(target_fabric_nacl_auth, se_node_acl, acl_auth_group);
 286
 287static struct configfs_item_operations target_fabric_nacl_auth_item_ops = {
 288        .show_attribute         = target_fabric_nacl_auth_attr_show,
 289        .store_attribute        = target_fabric_nacl_auth_attr_store,
 290};
 291
 292TF_CIT_SETUP(tpg_nacl_auth, &target_fabric_nacl_auth_item_ops, NULL, NULL);
 293
 294/* End of tfc_tpg_nacl_auth_cit */
 295
 296/* Start of tfc_tpg_nacl_param_cit */
 297
 298CONFIGFS_EATTR_OPS(target_fabric_nacl_param, se_node_acl, acl_param_group);
 299
 300static struct configfs_item_operations target_fabric_nacl_param_item_ops = {
 301        .show_attribute         = target_fabric_nacl_param_attr_show,
 302        .store_attribute        = target_fabric_nacl_param_attr_store,
 303};
 304
 305TF_CIT_SETUP(tpg_nacl_param, &target_fabric_nacl_param_item_ops, NULL, NULL);
 306
 307/* End of tfc_tpg_nacl_param_cit */
 308
 309/* Start of tfc_tpg_nacl_base_cit */
 310
 311CONFIGFS_EATTR_OPS(target_fabric_nacl_base, se_node_acl, acl_group);
 312
 313static struct config_group *target_fabric_make_mappedlun(
 314        struct config_group *group,
 315        const char *name)
 316{
 317        struct se_node_acl *se_nacl = container_of(group,
 318                        struct se_node_acl, acl_group);
 319        struct se_portal_group *se_tpg = se_nacl->se_tpg;
 320        struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
 321        struct se_lun_acl *lacl;
 322        struct config_item *acl_ci;
 323        struct config_group *lacl_cg = NULL, *ml_stat_grp = NULL;
 324        char *buf;
 325        unsigned long mapped_lun;
 326        int ret = 0;
 327
 328        acl_ci = &group->cg_item;
 329        if (!acl_ci) {
 330                pr_err("Unable to locatel acl_ci\n");
 331                return NULL;
 332        }
 333
 334        buf = kzalloc(strlen(name) + 1, GFP_KERNEL);
 335        if (!buf) {
 336                pr_err("Unable to allocate memory for name buf\n");
 337                return ERR_PTR(-ENOMEM);
 338        }
 339        snprintf(buf, strlen(name) + 1, "%s", name);
 340        /*
 341         * Make sure user is creating iscsi/$IQN/$TPGT/acls/$INITIATOR/lun_$ID.
 342         */
 343        if (strstr(buf, "lun_") != buf) {
 344                pr_err("Unable to locate \"lun_\" from buf: %s"
 345                        " name: %s\n", buf, name);
 346                ret = -EINVAL;
 347                goto out;
 348        }
 349        /*
 350         * Determine the Mapped LUN value.  This is what the SCSI Initiator
 351         * Port will actually see.
 352         */
 353        if (strict_strtoul(buf + 4, 0, &mapped_lun) || mapped_lun > UINT_MAX) {
 354                ret = -EINVAL;
 355                goto out;
 356        }
 357        if (mapped_lun > (TRANSPORT_MAX_LUNS_PER_TPG-1)) {
 358                pr_err("Mapped LUN: %lu exceeds TRANSPORT_MAX_LUNS_PER_TPG"
 359                        "-1: %u for Target Portal Group: %u\n", mapped_lun,
 360                        TRANSPORT_MAX_LUNS_PER_TPG-1,
 361                        se_tpg->se_tpg_tfo->tpg_get_tag(se_tpg));
 362                ret = -EINVAL;
 363                goto out;
 364        }
 365
 366        lacl = core_dev_init_initiator_node_lun_acl(se_tpg, se_nacl,
 367                        mapped_lun, &ret);
 368        if (!lacl) {
 369                ret = -EINVAL;
 370                goto out;
 371        }
 372
 373        lacl_cg = &lacl->se_lun_group;
 374        lacl_cg->default_groups = kmalloc(sizeof(struct config_group *) * 2,
 375                                GFP_KERNEL);
 376        if (!lacl_cg->default_groups) {
 377                pr_err("Unable to allocate lacl_cg->default_groups\n");
 378                ret = -ENOMEM;
 379                goto out;
 380        }
 381
 382        config_group_init_type_name(&lacl->se_lun_group, name,
 383                        &TF_CIT_TMPL(tf)->tfc_tpg_mappedlun_cit);
 384        config_group_init_type_name(&lacl->ml_stat_grps.stat_group,
 385                        "statistics", &TF_CIT_TMPL(tf)->tfc_tpg_mappedlun_stat_cit);
 386        lacl_cg->default_groups[0] = &lacl->ml_stat_grps.stat_group;
 387        lacl_cg->default_groups[1] = NULL;
 388
 389        ml_stat_grp = &lacl->ml_stat_grps.stat_group;
 390        ml_stat_grp->default_groups = kmalloc(sizeof(struct config_group *) * 3,
 391                                GFP_KERNEL);
 392        if (!ml_stat_grp->default_groups) {
 393                pr_err("Unable to allocate ml_stat_grp->default_groups\n");
 394                ret = -ENOMEM;
 395                goto out;
 396        }
 397        target_stat_setup_mappedlun_default_groups(lacl);
 398
 399        kfree(buf);
 400        return &lacl->se_lun_group;
 401out:
 402        if (lacl_cg)
 403                kfree(lacl_cg->default_groups);
 404        kfree(buf);
 405        return ERR_PTR(ret);
 406}
 407
 408static void target_fabric_drop_mappedlun(
 409        struct config_group *group,
 410        struct config_item *item)
 411{
 412        struct se_lun_acl *lacl = container_of(to_config_group(item),
 413                        struct se_lun_acl, se_lun_group);
 414        struct config_item *df_item;
 415        struct config_group *lacl_cg = NULL, *ml_stat_grp = NULL;
 416        int i;
 417
 418        ml_stat_grp = &lacl->ml_stat_grps.stat_group;
 419        for (i = 0; ml_stat_grp->default_groups[i]; i++) {
 420                df_item = &ml_stat_grp->default_groups[i]->cg_item;
 421                ml_stat_grp->default_groups[i] = NULL;
 422                config_item_put(df_item);
 423        }
 424        kfree(ml_stat_grp->default_groups);
 425
 426        lacl_cg = &lacl->se_lun_group;
 427        for (i = 0; lacl_cg->default_groups[i]; i++) {
 428                df_item = &lacl_cg->default_groups[i]->cg_item;
 429                lacl_cg->default_groups[i] = NULL;
 430                config_item_put(df_item);
 431        }
 432        kfree(lacl_cg->default_groups);
 433
 434        config_item_put(item);
 435}
 436
 437static void target_fabric_nacl_base_release(struct config_item *item)
 438{
 439        struct se_node_acl *se_nacl = container_of(to_config_group(item),
 440                        struct se_node_acl, acl_group);
 441        struct se_portal_group *se_tpg = se_nacl->se_tpg;
 442        struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
 443
 444        tf->tf_ops.fabric_drop_nodeacl(se_nacl);
 445}
 446
 447static struct configfs_item_operations target_fabric_nacl_base_item_ops = {
 448        .release                = target_fabric_nacl_base_release,
 449        .show_attribute         = target_fabric_nacl_base_attr_show,
 450        .store_attribute        = target_fabric_nacl_base_attr_store,
 451};
 452
 453static struct configfs_group_operations target_fabric_nacl_base_group_ops = {
 454        .make_group             = target_fabric_make_mappedlun,
 455        .drop_item              = target_fabric_drop_mappedlun,
 456};
 457
 458TF_CIT_SETUP(tpg_nacl_base, &target_fabric_nacl_base_item_ops,
 459                &target_fabric_nacl_base_group_ops, NULL);
 460
 461/* End of tfc_tpg_nacl_base_cit */
 462
 463/* Start of tfc_node_fabric_stats_cit */
 464/*
 465 * This is used as a placeholder for struct se_node_acl->acl_fabric_stat_group
 466 * to allow fabrics access to ->acl_fabric_stat_group->default_groups[]
 467 */
 468TF_CIT_SETUP(tpg_nacl_stat, NULL, NULL, NULL);
 469
 470/* End of tfc_wwn_fabric_stats_cit */
 471
 472/* Start of tfc_tpg_nacl_cit */
 473
 474static struct config_group *target_fabric_make_nodeacl(
 475        struct config_group *group,
 476        const char *name)
 477{
 478        struct se_portal_group *se_tpg = container_of(group,
 479                        struct se_portal_group, tpg_acl_group);
 480        struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
 481        struct se_node_acl *se_nacl;
 482        struct config_group *nacl_cg;
 483
 484        if (!tf->tf_ops.fabric_make_nodeacl) {
 485                pr_err("tf->tf_ops.fabric_make_nodeacl is NULL\n");
 486                return ERR_PTR(-ENOSYS);
 487        }
 488
 489        se_nacl = tf->tf_ops.fabric_make_nodeacl(se_tpg, group, name);
 490        if (IS_ERR(se_nacl))
 491                return ERR_CAST(se_nacl);
 492
 493        nacl_cg = &se_nacl->acl_group;
 494        nacl_cg->default_groups = se_nacl->acl_default_groups;
 495        nacl_cg->default_groups[0] = &se_nacl->acl_attrib_group;
 496        nacl_cg->default_groups[1] = &se_nacl->acl_auth_group;
 497        nacl_cg->default_groups[2] = &se_nacl->acl_param_group;
 498        nacl_cg->default_groups[3] = &se_nacl->acl_fabric_stat_group;
 499        nacl_cg->default_groups[4] = NULL;
 500
 501        config_group_init_type_name(&se_nacl->acl_group, name,
 502                        &TF_CIT_TMPL(tf)->tfc_tpg_nacl_base_cit);
 503        config_group_init_type_name(&se_nacl->acl_attrib_group, "attrib",
 504                        &TF_CIT_TMPL(tf)->tfc_tpg_nacl_attrib_cit);
 505        config_group_init_type_name(&se_nacl->acl_auth_group, "auth",
 506                        &TF_CIT_TMPL(tf)->tfc_tpg_nacl_auth_cit);
 507        config_group_init_type_name(&se_nacl->acl_param_group, "param",
 508                        &TF_CIT_TMPL(tf)->tfc_tpg_nacl_param_cit);
 509        config_group_init_type_name(&se_nacl->acl_fabric_stat_group,
 510                        "fabric_statistics",
 511                        &TF_CIT_TMPL(tf)->tfc_tpg_nacl_stat_cit);
 512
 513        return &se_nacl->acl_group;
 514}
 515
 516static void target_fabric_drop_nodeacl(
 517        struct config_group *group,
 518        struct config_item *item)
 519{
 520        struct se_node_acl *se_nacl = container_of(to_config_group(item),
 521                        struct se_node_acl, acl_group);
 522        struct config_item *df_item;
 523        struct config_group *nacl_cg;
 524        int i;
 525
 526        nacl_cg = &se_nacl->acl_group;
 527        for (i = 0; nacl_cg->default_groups[i]; i++) {
 528                df_item = &nacl_cg->default_groups[i]->cg_item;
 529                nacl_cg->default_groups[i] = NULL;
 530                config_item_put(df_item);
 531        }
 532        /*
 533         * struct se_node_acl free is done in target_fabric_nacl_base_release()
 534         */
 535        config_item_put(item);
 536}
 537
 538static struct configfs_group_operations target_fabric_nacl_group_ops = {
 539        .make_group     = target_fabric_make_nodeacl,
 540        .drop_item      = target_fabric_drop_nodeacl,
 541};
 542
 543TF_CIT_SETUP(tpg_nacl, NULL, &target_fabric_nacl_group_ops, NULL);
 544
 545/* End of tfc_tpg_nacl_cit */
 546
 547/* Start of tfc_tpg_np_base_cit */
 548
 549CONFIGFS_EATTR_OPS(target_fabric_np_base, se_tpg_np, tpg_np_group);
 550
 551static void target_fabric_np_base_release(struct config_item *item)
 552{
 553        struct se_tpg_np *se_tpg_np = container_of(to_config_group(item),
 554                                struct se_tpg_np, tpg_np_group);
 555        struct se_portal_group *se_tpg = se_tpg_np->tpg_np_parent;
 556        struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
 557
 558        tf->tf_ops.fabric_drop_np(se_tpg_np);
 559}
 560
 561static struct configfs_item_operations target_fabric_np_base_item_ops = {
 562        .release                = target_fabric_np_base_release,
 563        .show_attribute         = target_fabric_np_base_attr_show,
 564        .store_attribute        = target_fabric_np_base_attr_store,
 565};
 566
 567TF_CIT_SETUP(tpg_np_base, &target_fabric_np_base_item_ops, NULL, NULL);
 568
 569/* End of tfc_tpg_np_base_cit */
 570
 571/* Start of tfc_tpg_np_cit */
 572
 573static struct config_group *target_fabric_make_np(
 574        struct config_group *group,
 575        const char *name)
 576{
 577        struct se_portal_group *se_tpg = container_of(group,
 578                                struct se_portal_group, tpg_np_group);
 579        struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
 580        struct se_tpg_np *se_tpg_np;
 581
 582        if (!tf->tf_ops.fabric_make_np) {
 583                pr_err("tf->tf_ops.fabric_make_np is NULL\n");
 584                return ERR_PTR(-ENOSYS);
 585        }
 586
 587        se_tpg_np = tf->tf_ops.fabric_make_np(se_tpg, group, name);
 588        if (!se_tpg_np || IS_ERR(se_tpg_np))
 589                return ERR_PTR(-EINVAL);
 590
 591        se_tpg_np->tpg_np_parent = se_tpg;
 592        config_group_init_type_name(&se_tpg_np->tpg_np_group, name,
 593                        &TF_CIT_TMPL(tf)->tfc_tpg_np_base_cit);
 594
 595        return &se_tpg_np->tpg_np_group;
 596}
 597
 598static void target_fabric_drop_np(
 599        struct config_group *group,
 600        struct config_item *item)
 601{
 602        /*
 603         * struct se_tpg_np is released via target_fabric_np_base_release()
 604         */
 605        config_item_put(item);
 606}
 607
 608static struct configfs_group_operations target_fabric_np_group_ops = {
 609        .make_group     = &target_fabric_make_np,
 610        .drop_item      = &target_fabric_drop_np,
 611};
 612
 613TF_CIT_SETUP(tpg_np, NULL, &target_fabric_np_group_ops, NULL);
 614
 615/* End of tfc_tpg_np_cit */
 616
 617/* Start of tfc_tpg_port_cit */
 618
 619CONFIGFS_EATTR_STRUCT(target_fabric_port, se_lun);
 620#define TCM_PORT_ATTR(_name, _mode)                                     \
 621static struct target_fabric_port_attribute target_fabric_port_##_name = \
 622        __CONFIGFS_EATTR(_name, _mode,                                  \
 623        target_fabric_port_show_attr_##_name,                           \
 624        target_fabric_port_store_attr_##_name);
 625
 626#define TCM_PORT_ATTOR_RO(_name)                                        \
 627        __CONFIGFS_EATTR_RO(_name,                                      \
 628        target_fabric_port_show_attr_##_name);
 629
 630/*
 631 * alua_tg_pt_gp
 632 */
 633static ssize_t target_fabric_port_show_attr_alua_tg_pt_gp(
 634        struct se_lun *lun,
 635        char *page)
 636{
 637        if (!lun || !lun->lun_sep)
 638                return -ENODEV;
 639
 640        return core_alua_show_tg_pt_gp_info(lun->lun_sep, page);
 641}
 642
 643static ssize_t target_fabric_port_store_attr_alua_tg_pt_gp(
 644        struct se_lun *lun,
 645        const char *page,
 646        size_t count)
 647{
 648        if (!lun || !lun->lun_sep)
 649                return -ENODEV;
 650
 651        return core_alua_store_tg_pt_gp_info(lun->lun_sep, page, count);
 652}
 653
 654TCM_PORT_ATTR(alua_tg_pt_gp, S_IRUGO | S_IWUSR);
 655
 656/*
 657 * alua_tg_pt_offline
 658 */
 659static ssize_t target_fabric_port_show_attr_alua_tg_pt_offline(
 660        struct se_lun *lun,
 661        char *page)
 662{
 663        if (!lun || !lun->lun_sep)
 664                return -ENODEV;
 665
 666        return core_alua_show_offline_bit(lun, page);
 667}
 668
 669static ssize_t target_fabric_port_store_attr_alua_tg_pt_offline(
 670        struct se_lun *lun,
 671        const char *page,
 672        size_t count)
 673{
 674        if (!lun || !lun->lun_sep)
 675                return -ENODEV;
 676
 677        return core_alua_store_offline_bit(lun, page, count);
 678}
 679
 680TCM_PORT_ATTR(alua_tg_pt_offline, S_IRUGO | S_IWUSR);
 681
 682/*
 683 * alua_tg_pt_status
 684 */
 685static ssize_t target_fabric_port_show_attr_alua_tg_pt_status(
 686        struct se_lun *lun,
 687        char *page)
 688{
 689        if (!lun || !lun->lun_sep)
 690                return -ENODEV;
 691
 692        return core_alua_show_secondary_status(lun, page);
 693}
 694
 695static ssize_t target_fabric_port_store_attr_alua_tg_pt_status(
 696        struct se_lun *lun,
 697        const char *page,
 698        size_t count)
 699{
 700        if (!lun || !lun->lun_sep)
 701                return -ENODEV;
 702
 703        return core_alua_store_secondary_status(lun, page, count);
 704}
 705
 706TCM_PORT_ATTR(alua_tg_pt_status, S_IRUGO | S_IWUSR);
 707
 708/*
 709 * alua_tg_pt_write_md
 710 */
 711static ssize_t target_fabric_port_show_attr_alua_tg_pt_write_md(
 712        struct se_lun *lun,
 713        char *page)
 714{
 715        if (!lun || !lun->lun_sep)
 716                return -ENODEV;
 717
 718        return core_alua_show_secondary_write_metadata(lun, page);
 719}
 720
 721static ssize_t target_fabric_port_store_attr_alua_tg_pt_write_md(
 722        struct se_lun *lun,
 723        const char *page,
 724        size_t count)
 725{
 726        if (!lun || !lun->lun_sep)
 727                return -ENODEV;
 728
 729        return core_alua_store_secondary_write_metadata(lun, page, count);
 730}
 731
 732TCM_PORT_ATTR(alua_tg_pt_write_md, S_IRUGO | S_IWUSR);
 733
 734
 735static struct configfs_attribute *target_fabric_port_attrs[] = {
 736        &target_fabric_port_alua_tg_pt_gp.attr,
 737        &target_fabric_port_alua_tg_pt_offline.attr,
 738        &target_fabric_port_alua_tg_pt_status.attr,
 739        &target_fabric_port_alua_tg_pt_write_md.attr,
 740        NULL,
 741};
 742
 743CONFIGFS_EATTR_OPS(target_fabric_port, se_lun, lun_group);
 744
 745static int target_fabric_port_link(
 746        struct config_item *lun_ci,
 747        struct config_item *se_dev_ci)
 748{
 749        struct config_item *tpg_ci;
 750        struct se_lun *lun = container_of(to_config_group(lun_ci),
 751                                struct se_lun, lun_group);
 752        struct se_lun *lun_p;
 753        struct se_portal_group *se_tpg;
 754        struct se_device *dev =
 755                container_of(to_config_group(se_dev_ci), struct se_device, dev_group);
 756        struct target_fabric_configfs *tf;
 757        int ret;
 758
 759        if (dev->dev_link_magic != SE_DEV_LINK_MAGIC) {
 760                pr_err("Bad dev->dev_link_magic, not a valid se_dev_ci pointer:"
 761                        " %p to struct se_device: %p\n", se_dev_ci, dev);
 762                return -EFAULT;
 763        }
 764
 765        if (!(dev->dev_flags & DF_CONFIGURED)) {
 766                pr_err("se_device not configured yet, cannot port link\n");
 767                return -ENODEV;
 768        }
 769
 770        tpg_ci = &lun_ci->ci_parent->ci_group->cg_item;
 771        se_tpg = container_of(to_config_group(tpg_ci),
 772                                struct se_portal_group, tpg_group);
 773        tf = se_tpg->se_tpg_wwn->wwn_tf;
 774
 775        if (lun->lun_se_dev !=  NULL) {
 776                pr_err("Port Symlink already exists\n");
 777                return -EEXIST;
 778        }
 779
 780        lun_p = core_dev_add_lun(se_tpg, dev, lun->unpacked_lun);
 781        if (IS_ERR(lun_p)) {
 782                pr_err("core_dev_add_lun() failed\n");
 783                ret = PTR_ERR(lun_p);
 784                goto out;
 785        }
 786
 787        if (tf->tf_ops.fabric_post_link) {
 788                /*
 789                 * Call the optional fabric_post_link() to allow a
 790                 * fabric module to setup any additional state once
 791                 * core_dev_add_lun() has been called..
 792                 */
 793                tf->tf_ops.fabric_post_link(se_tpg, lun);
 794        }
 795
 796        return 0;
 797out:
 798        return ret;
 799}
 800
 801static int target_fabric_port_unlink(
 802        struct config_item *lun_ci,
 803        struct config_item *se_dev_ci)
 804{
 805        struct se_lun *lun = container_of(to_config_group(lun_ci),
 806                                struct se_lun, lun_group);
 807        struct se_portal_group *se_tpg = lun->lun_sep->sep_tpg;
 808        struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
 809
 810        if (tf->tf_ops.fabric_pre_unlink) {
 811                /*
 812                 * Call the optional fabric_pre_unlink() to allow a
 813                 * fabric module to release any additional stat before
 814                 * core_dev_del_lun() is called.
 815                */
 816                tf->tf_ops.fabric_pre_unlink(se_tpg, lun);
 817        }
 818
 819        core_dev_del_lun(se_tpg, lun->unpacked_lun);
 820        return 0;
 821}
 822
 823static struct configfs_item_operations target_fabric_port_item_ops = {
 824        .show_attribute         = target_fabric_port_attr_show,
 825        .store_attribute        = target_fabric_port_attr_store,
 826        .allow_link             = target_fabric_port_link,
 827        .drop_link              = target_fabric_port_unlink,
 828};
 829
 830TF_CIT_SETUP(tpg_port, &target_fabric_port_item_ops, NULL, target_fabric_port_attrs);
 831
 832/* End of tfc_tpg_port_cit */
 833
 834/* Start of tfc_tpg_port_stat_cit */
 835
 836static struct config_group *target_core_port_stat_mkdir(
 837        struct config_group *group,
 838        const char *name)
 839{
 840        return ERR_PTR(-ENOSYS);
 841}
 842
 843static void target_core_port_stat_rmdir(
 844        struct config_group *group,
 845        struct config_item *item)
 846{
 847        return;
 848}
 849
 850static struct configfs_group_operations target_fabric_port_stat_group_ops = {
 851        .make_group             = target_core_port_stat_mkdir,
 852        .drop_item              = target_core_port_stat_rmdir,
 853};
 854
 855TF_CIT_SETUP(tpg_port_stat, NULL, &target_fabric_port_stat_group_ops, NULL);
 856
 857/* End of tfc_tpg_port_stat_cit */
 858
 859/* Start of tfc_tpg_lun_cit */
 860
 861static struct config_group *target_fabric_make_lun(
 862        struct config_group *group,
 863        const char *name)
 864{
 865        struct se_lun *lun;
 866        struct se_portal_group *se_tpg = container_of(group,
 867                        struct se_portal_group, tpg_lun_group);
 868        struct target_fabric_configfs *tf = se_tpg->se_tpg_wwn->wwn_tf;
 869        struct config_group *lun_cg = NULL, *port_stat_grp = NULL;
 870        unsigned long unpacked_lun;
 871        int errno;
 872
 873        if (strstr(name, "lun_") != name) {
 874                pr_err("Unable to locate \'_\" in"
 875                                " \"lun_$LUN_NUMBER\"\n");
 876                return ERR_PTR(-EINVAL);
 877        }
 878        if (strict_strtoul(name + 4, 0, &unpacked_lun) || unpacked_lun > UINT_MAX)
 879                return ERR_PTR(-EINVAL);
 880
 881        lun = core_get_lun_from_tpg(se_tpg, unpacked_lun);
 882        if (!lun)
 883                return ERR_PTR(-EINVAL);
 884
 885        lun_cg = &lun->lun_group;
 886        lun_cg->default_groups = kmalloc(sizeof(struct config_group *) * 2,
 887                                GFP_KERNEL);
 888        if (!lun_cg->default_groups) {
 889                pr_err("Unable to allocate lun_cg->default_groups\n");
 890                return ERR_PTR(-ENOMEM);
 891        }
 892
 893        config_group_init_type_name(&lun->lun_group, name,
 894                        &TF_CIT_TMPL(tf)->tfc_tpg_port_cit);
 895        config_group_init_type_name(&lun->port_stat_grps.stat_group,
 896                        "statistics", &TF_CIT_TMPL(tf)->tfc_tpg_port_stat_cit);
 897        lun_cg->default_groups[0] = &lun->port_stat_grps.stat_group;
 898        lun_cg->default_groups[1] = NULL;
 899
 900        port_stat_grp = &lun->port_stat_grps.stat_group;
 901        port_stat_grp->default_groups =  kzalloc(sizeof(struct config_group) * 3,
 902                                GFP_KERNEL);
 903        if (!port_stat_grp->default_groups) {
 904                pr_err("Unable to allocate port_stat_grp->default_groups\n");
 905                errno = -ENOMEM;
 906                goto out;
 907        }
 908        target_stat_setup_port_default_groups(lun);
 909
 910        return &lun->lun_group;
 911out:
 912        if (lun_cg)
 913                kfree(lun_cg->default_groups);
 914        return ERR_PTR(errno);
 915}
 916
 917static void target_fabric_drop_lun(
 918        struct config_group *group,
 919        struct config_item *item)
 920{
 921        struct se_lun *lun = container_of(to_config_group(item),
 922                                struct se_lun, lun_group);
 923        struct config_item *df_item;
 924        struct config_group *lun_cg, *port_stat_grp;
 925        int i;
 926
 927        port_stat_grp = &lun->port_stat_grps.stat_group;
 928        for (i = 0; port_stat_grp->default_groups[i]; i++) {
 929                df_item = &port_stat_grp->default_groups[i]->cg_item;
 930                port_stat_grp->default_groups[i] = NULL;
 931                config_item_put(df_item);
 932        }
 933        kfree(port_stat_grp->default_groups);
 934
 935        lun_cg = &lun->lun_group;
 936        for (i = 0; lun_cg->default_groups[i]; i++) {
 937                df_item = &lun_cg->default_groups[i]->cg_item;
 938                lun_cg->default_groups[i] = NULL;
 939                config_item_put(df_item);
 940        }
 941        kfree(lun_cg->default_groups);
 942
 943        config_item_put(item);
 944}
 945
 946static struct configfs_group_operations target_fabric_lun_group_ops = {
 947        .make_group     = &target_fabric_make_lun,
 948        .drop_item      = &target_fabric_drop_lun,
 949};
 950
 951TF_CIT_SETUP(tpg_lun, NULL, &target_fabric_lun_group_ops, NULL);
 952
 953/* End of tfc_tpg_lun_cit */
 954
 955/* Start of tfc_tpg_attrib_cit */
 956
 957CONFIGFS_EATTR_OPS(target_fabric_tpg_attrib, se_portal_group, tpg_attrib_group);
 958
 959static struct configfs_item_operations target_fabric_tpg_attrib_item_ops = {
 960        .show_attribute         = target_fabric_tpg_attrib_attr_show,
 961        .store_attribute        = target_fabric_tpg_attrib_attr_store,
 962};
 963
 964TF_CIT_SETUP(tpg_attrib, &target_fabric_tpg_attrib_item_ops, NULL, NULL);
 965
 966/* End of tfc_tpg_attrib_cit */
 967
 968/* Start of tfc_tpg_param_cit */
 969
 970CONFIGFS_EATTR_OPS(target_fabric_tpg_param, se_portal_group, tpg_param_group);
 971
 972static struct configfs_item_operations target_fabric_tpg_param_item_ops = {
 973        .show_attribute         = target_fabric_tpg_param_attr_show,
 974        .store_attribute        = target_fabric_tpg_param_attr_store,
 975};
 976
 977TF_CIT_SETUP(tpg_param, &target_fabric_tpg_param_item_ops, NULL, NULL);
 978
 979/* End of tfc_tpg_param_cit */
 980
 981/* Start of tfc_tpg_base_cit */
 982/*
 983 * For use with TF_TPG_ATTR() and TF_TPG_ATTR_RO()
 984 */
 985CONFIGFS_EATTR_OPS(target_fabric_tpg, se_portal_group, tpg_group);
 986
 987static void target_fabric_tpg_release(struct config_item *item)
 988{
 989        struct se_portal_group *se_tpg = container_of(to_config_group(item),
 990                        struct se_portal_group, tpg_group);
 991        struct se_wwn *wwn = se_tpg->se_tpg_wwn;
 992        struct target_fabric_configfs *tf = wwn->wwn_tf;
 993
 994        tf->tf_ops.fabric_drop_tpg(se_tpg);
 995}
 996
 997static struct configfs_item_operations target_fabric_tpg_base_item_ops = {
 998        .release                = target_fabric_tpg_release,
 999        .show_attribute         = target_fabric_tpg_attr_show,
1000        .store_attribute        = target_fabric_tpg_attr_store,
1001};
1002
1003TF_CIT_SETUP(tpg_base, &target_fabric_tpg_base_item_ops, NULL, NULL);
1004
1005/* End of tfc_tpg_base_cit */
1006
1007/* Start of tfc_tpg_cit */
1008
1009static struct config_group *target_fabric_make_tpg(
1010        struct config_group *group,
1011        const char *name)
1012{
1013        struct se_wwn *wwn = container_of(group, struct se_wwn, wwn_group);
1014        struct target_fabric_configfs *tf = wwn->wwn_tf;
1015        struct se_portal_group *se_tpg;
1016
1017        if (!tf->tf_ops.fabric_make_tpg) {
1018                pr_err("tf->tf_ops.fabric_make_tpg is NULL\n");
1019                return ERR_PTR(-ENOSYS);
1020        }
1021
1022        se_tpg = tf->tf_ops.fabric_make_tpg(wwn, group, name);
1023        if (!se_tpg || IS_ERR(se_tpg))
1024                return ERR_PTR(-EINVAL);
1025        /*
1026         * Setup default groups from pre-allocated se_tpg->tpg_default_groups
1027         */
1028        se_tpg->tpg_group.default_groups = se_tpg->tpg_default_groups;
1029        se_tpg->tpg_group.default_groups[0] = &se_tpg->tpg_lun_group;
1030        se_tpg->tpg_group.default_groups[1] = &se_tpg->tpg_np_group;
1031        se_tpg->tpg_group.default_groups[2] = &se_tpg->tpg_acl_group;
1032        se_tpg->tpg_group.default_groups[3] = &se_tpg->tpg_attrib_group;
1033        se_tpg->tpg_group.default_groups[4] = &se_tpg->tpg_param_group;
1034        se_tpg->tpg_group.default_groups[5] = NULL;
1035
1036        config_group_init_type_name(&se_tpg->tpg_group, name,
1037                        &TF_CIT_TMPL(tf)->tfc_tpg_base_cit);
1038        config_group_init_type_name(&se_tpg->tpg_lun_group, "lun",
1039                        &TF_CIT_TMPL(tf)->tfc_tpg_lun_cit);
1040        config_group_init_type_name(&se_tpg->tpg_np_group, "np",
1041                        &TF_CIT_TMPL(tf)->tfc_tpg_np_cit);
1042        config_group_init_type_name(&se_tpg->tpg_acl_group, "acls",
1043                        &TF_CIT_TMPL(tf)->tfc_tpg_nacl_cit);
1044        config_group_init_type_name(&se_tpg->tpg_attrib_group, "attrib",
1045                        &TF_CIT_TMPL(tf)->tfc_tpg_attrib_cit);
1046        config_group_init_type_name(&se_tpg->tpg_param_group, "param",
1047                        &TF_CIT_TMPL(tf)->tfc_tpg_param_cit);
1048
1049        return &se_tpg->tpg_group;
1050}
1051
1052static void target_fabric_drop_tpg(
1053        struct config_group *group,
1054        struct config_item *item)
1055{
1056        struct se_portal_group *se_tpg = container_of(to_config_group(item),
1057                                struct se_portal_group, tpg_group);
1058        struct config_group *tpg_cg = &se_tpg->tpg_group;
1059        struct config_item *df_item;
1060        int i;
1061        /*
1062         * Release default groups, but do not release tpg_cg->default_groups
1063         * memory as it is statically allocated at se_tpg->tpg_default_groups.
1064         */
1065        for (i = 0; tpg_cg->default_groups[i]; i++) {
1066                df_item = &tpg_cg->default_groups[i]->cg_item;
1067                tpg_cg->default_groups[i] = NULL;
1068                config_item_put(df_item);
1069        }
1070
1071        config_item_put(item);
1072}
1073
1074static void target_fabric_release_wwn(struct config_item *item)
1075{
1076        struct se_wwn *wwn = container_of(to_config_group(item),
1077                                struct se_wwn, wwn_group);
1078        struct target_fabric_configfs *tf = wwn->wwn_tf;
1079
1080        tf->tf_ops.fabric_drop_wwn(wwn);
1081}
1082
1083static struct configfs_item_operations target_fabric_tpg_item_ops = {
1084        .release        = target_fabric_release_wwn,
1085};
1086
1087static struct configfs_group_operations target_fabric_tpg_group_ops = {
1088        .make_group     = target_fabric_make_tpg,
1089        .drop_item      = target_fabric_drop_tpg,
1090};
1091
1092TF_CIT_SETUP(tpg, &target_fabric_tpg_item_ops, &target_fabric_tpg_group_ops,
1093                NULL);
1094
1095/* End of tfc_tpg_cit */
1096
1097/* Start of tfc_wwn_fabric_stats_cit */
1098/*
1099 * This is used as a placeholder for struct se_wwn->fabric_stat_group
1100 * to allow fabrics access to ->fabric_stat_group->default_groups[]
1101 */
1102TF_CIT_SETUP(wwn_fabric_stats, NULL, NULL, NULL);
1103
1104/* End of tfc_wwn_fabric_stats_cit */
1105
1106/* Start of tfc_wwn_cit */
1107
1108static struct config_group *target_fabric_make_wwn(
1109        struct config_group *group,
1110        const char *name)
1111{
1112        struct target_fabric_configfs *tf = container_of(group,
1113                                struct target_fabric_configfs, tf_group);
1114        struct se_wwn *wwn;
1115
1116        if (!tf->tf_ops.fabric_make_wwn) {
1117                pr_err("tf->tf_ops.fabric_make_wwn is NULL\n");
1118                return ERR_PTR(-ENOSYS);
1119        }
1120
1121        wwn = tf->tf_ops.fabric_make_wwn(tf, group, name);
1122        if (!wwn || IS_ERR(wwn))
1123                return ERR_PTR(-EINVAL);
1124
1125        wwn->wwn_tf = tf;
1126        /*
1127         * Setup default groups from pre-allocated wwn->wwn_default_groups
1128         */
1129        wwn->wwn_group.default_groups = wwn->wwn_default_groups;
1130        wwn->wwn_group.default_groups[0] = &wwn->fabric_stat_group;
1131        wwn->wwn_group.default_groups[1] = NULL;
1132
1133        config_group_init_type_name(&wwn->wwn_group, name,
1134                        &TF_CIT_TMPL(tf)->tfc_tpg_cit);
1135        config_group_init_type_name(&wwn->fabric_stat_group, "fabric_statistics",
1136                        &TF_CIT_TMPL(tf)->tfc_wwn_fabric_stats_cit);
1137
1138        return &wwn->wwn_group;
1139}
1140
1141static void target_fabric_drop_wwn(
1142        struct config_group *group,
1143        struct config_item *item)
1144{
1145        struct se_wwn *wwn = container_of(to_config_group(item),
1146                                struct se_wwn, wwn_group);
1147        struct config_item *df_item;
1148        struct config_group *cg = &wwn->wwn_group;
1149        int i;
1150
1151        for (i = 0; cg->default_groups[i]; i++) {
1152                df_item = &cg->default_groups[i]->cg_item;
1153                cg->default_groups[i] = NULL;
1154                config_item_put(df_item);
1155        }
1156
1157        config_item_put(item);
1158}
1159
1160static struct configfs_group_operations target_fabric_wwn_group_ops = {
1161        .make_group     = target_fabric_make_wwn,
1162        .drop_item      = target_fabric_drop_wwn,
1163};
1164/*
1165 * For use with TF_WWN_ATTR() and TF_WWN_ATTR_RO()
1166 */
1167CONFIGFS_EATTR_OPS(target_fabric_wwn, target_fabric_configfs, tf_group);
1168
1169static struct configfs_item_operations target_fabric_wwn_item_ops = {
1170        .show_attribute         = target_fabric_wwn_attr_show,
1171        .store_attribute        = target_fabric_wwn_attr_store,
1172};
1173
1174TF_CIT_SETUP(wwn, &target_fabric_wwn_item_ops, &target_fabric_wwn_group_ops, NULL);
1175
1176/* End of tfc_wwn_cit */
1177
1178/* Start of tfc_discovery_cit */
1179
1180CONFIGFS_EATTR_OPS(target_fabric_discovery, target_fabric_configfs,
1181                tf_disc_group);
1182
1183static struct configfs_item_operations target_fabric_discovery_item_ops = {
1184        .show_attribute         = target_fabric_discovery_attr_show,
1185        .store_attribute        = target_fabric_discovery_attr_store,
1186};
1187
1188TF_CIT_SETUP(discovery, &target_fabric_discovery_item_ops, NULL, NULL);
1189
1190/* End of tfc_discovery_cit */
1191
1192int target_fabric_setup_cits(struct target_fabric_configfs *tf)
1193{
1194        target_fabric_setup_discovery_cit(tf);
1195        target_fabric_setup_wwn_cit(tf);
1196        target_fabric_setup_wwn_fabric_stats_cit(tf);
1197        target_fabric_setup_tpg_cit(tf);
1198        target_fabric_setup_tpg_base_cit(tf);
1199        target_fabric_setup_tpg_port_cit(tf);
1200        target_fabric_setup_tpg_port_stat_cit(tf);
1201        target_fabric_setup_tpg_lun_cit(tf);
1202        target_fabric_setup_tpg_np_cit(tf);
1203        target_fabric_setup_tpg_np_base_cit(tf);
1204        target_fabric_setup_tpg_attrib_cit(tf);
1205        target_fabric_setup_tpg_param_cit(tf);
1206        target_fabric_setup_tpg_nacl_cit(tf);
1207        target_fabric_setup_tpg_nacl_base_cit(tf);
1208        target_fabric_setup_tpg_nacl_attrib_cit(tf);
1209        target_fabric_setup_tpg_nacl_auth_cit(tf);
1210        target_fabric_setup_tpg_nacl_param_cit(tf);
1211        target_fabric_setup_tpg_nacl_stat_cit(tf);
1212        target_fabric_setup_tpg_mappedlun_cit(tf);
1213        target_fabric_setup_tpg_mappedlun_stat_cit(tf);
1214
1215        return 0;
1216}
1217
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.