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) \ 47 static 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) \ 60 static 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 75 static 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 150 static 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 173 CONFIGFS_EATTR_STRUCT(target_fabric_mappedlun, se_lun_acl); 174 #define TCM_MAPPEDLUN_ATTR(_name, _mode) \ 175 static 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 180 static 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 198 static 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 229 TCM_MAPPEDLUN_ATTR(write_protect, S_IRUGO | S_IWUSR); 230 231 CONFIGFS_EATTR_OPS(target_fabric_mappedlun, se_lun_acl, se_lun_group); 232 233 static 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 242 static struct configfs_attribute *target_fabric_mappedlun_attrs[] = { 243 &target_fabric_mappedlun_write_protect.attr, 244 NULL, 245 }; 246 247 static 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 255 TF_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 262 static 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 269 static void target_core_mappedlun_stat_rmdir( 270 struct config_group *group, 271 struct config_item *item) 272 { 273 return; 274 } 275 276 static 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 281 TF_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 288 CONFIGFS_EATTR_OPS(target_fabric_nacl_attrib, se_node_acl, acl_attrib_group); 289 290 static 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 295 TF_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 301 CONFIGFS_EATTR_OPS(target_fabric_nacl_auth, se_node_acl, acl_auth_group); 302 303 static 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 308 TF_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 314 CONFIGFS_EATTR_OPS(target_fabric_nacl_param, se_node_acl, acl_param_group); 315 316 static 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 321 TF_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 327 CONFIGFS_EATTR_OPS(target_fabric_nacl_base, se_node_acl, acl_group); 328 329 static 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; 420 out: 421 if (lacl_cg) 422 kfree(lacl_cg->default_groups); 423 kfree(lacl); 424 kfree(buf); 425 return ERR_PTR(ret); 426 } 427 428 static 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 457 static 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 467 static 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 473 static 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 478 TF_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 */ 488 TF_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 494 static 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 536 static 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 558 static 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 563 TF_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 569 CONFIGFS_EATTR_OPS(target_fabric_np_base, se_tpg_np, tpg_np_group); 570 571 static 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 581 static 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 587 TF_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 593 static 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 618 static 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 628 static 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 633 TF_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 639 CONFIGFS_EATTR_STRUCT(target_fabric_port, se_lun); 640 #define TCM_PORT_ATTR(_name, _mode) \ 641 static 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 */ 653 static 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 663 static 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 674 TCM_PORT_ATTR(alua_tg_pt_gp, S_IRUGO | S_IWUSR); 675 676 /* 677 * alua_tg_pt_offline 678 */ 679 static 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 689 static 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 700 TCM_PORT_ATTR(alua_tg_pt_offline, S_IRUGO | S_IWUSR); 701 702 /* 703 * alua_tg_pt_status 704 */ 705 static 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 715 static 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 726 TCM_PORT_ATTR(alua_tg_pt_status, S_IRUGO | S_IWUSR); 727 728 /* 729 * alua_tg_pt_write_md 730 */ 731 static 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 741 static 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 752 TCM_PORT_ATTR(alua_tg_pt_write_md, S_IRUGO | S_IWUSR); 753 754 755 static 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 763 CONFIGFS_EATTR_OPS(target_fabric_port, se_lun, lun_group); 764 765 static 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; 817 out: 818 return ret; 819 } 820 821 static 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 843 static 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 850 TF_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 856 static 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 863 static void target_core_port_stat_rmdir( 864 struct config_group *group, 865 struct config_item *item) 866 { 867 return; 868 } 869 870 static 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 875 TF_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 881 static 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 936 static 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 965 static 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 970 TF_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 976 CONFIGFS_EATTR_OPS(target_fabric_tpg_attrib, se_portal_group, tpg_attrib_group); 977 978 static 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 983 TF_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 989 CONFIGFS_EATTR_OPS(target_fabric_tpg_auth, se_portal_group, tpg_auth_group); 990 991 static 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 996 TF_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 1002 CONFIGFS_EATTR_OPS(target_fabric_tpg_param, se_portal_group, tpg_param_group); 1003 1004 static 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 1009 TF_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 */ 1017 CONFIGFS_EATTR_OPS(target_fabric_tpg, se_portal_group, tpg_group); 1018 1019 static 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 1029 static 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 1035 TF_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 1041 static 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 1087 static 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 1109 static 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 1118 static struct configfs_item_operations target_fabric_tpg_item_ops = { 1119 .release = target_fabric_release_wwn, 1120 }; 1121 1122 static 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 1127 TF_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 */ 1137 TF_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 1143 static 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 1176 static 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 1195 static 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 */ 1202 CONFIGFS_EATTR_OPS(target_fabric_wwn, target_fabric_configfs, tf_group); 1203 1204 static 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 1209 TF_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 1215 CONFIGFS_EATTR_OPS(target_fabric_discovery, target_fabric_configfs, 1216 tf_disc_group); 1217 1218 static 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 1223 TF_CIT_SETUP_DRV(discovery, &target_fabric_discovery_item_ops, NULL); 1224 1225 /* End of tfc_discovery_cit */ 1226 1227 int 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