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