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