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