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