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