target_core_fabric_configfs.c (31096B)
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) \ 37static 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) \ 49static 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 61static struct configfs_item_operations target_fabric_port_item_ops; 62 63/* Start of tfc_tpg_mappedlun_cit */ 64 65static 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 141static 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 153static 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 159static 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 177static 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 205CONFIGFS_ATTR(target_fabric_mappedlun_, write_protect); 206 207static struct configfs_attribute *target_fabric_mappedlun_attrs[] = { 208 &target_fabric_mappedlun_attr_write_protect, 209 NULL, 210}; 211 212static 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 221static 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 227TF_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 234static 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 241static void target_core_mappedlun_stat_rmdir( 242 struct config_group *group, 243 struct config_item *item) 244{ 245 return; 246} 247 248static 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 253TF_CIT_SETUP(tpg_mappedlun_stat, NULL, &target_fabric_mappedlun_stat_group_ops, 254 NULL); 255 256/* End of tfc_tpg_mappedlun_port_cit */ 257 258TF_CIT_SETUP_DRV(tpg_nacl_attrib, NULL, NULL); 259TF_CIT_SETUP_DRV(tpg_nacl_auth, NULL, NULL); 260TF_CIT_SETUP_DRV(tpg_nacl_param, NULL, NULL); 261 262/* Start of tfc_tpg_nacl_base_cit */ 263 264static 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; 319out: 320 kfree(lacl); 321 kfree(buf); 322 return ERR_PTR(ret); 323} 324 325static 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 338static 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 347static struct configfs_item_operations target_fabric_nacl_base_item_ops = { 348 .release = target_fabric_nacl_base_release, 349}; 350 351static 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 356TF_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 */ 366TF_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 372static 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 420static 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 435static 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 440TF_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 446static 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 456static struct configfs_item_operations target_fabric_np_base_item_ops = { 457 .release = target_fabric_np_base_release, 458}; 459 460TF_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 466static 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 491static 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 501static 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 506TF_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 512static 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 518static 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 529static 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 540static 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 551static 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 562static 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 573static 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 584static 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 595static 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 606CONFIGFS_ATTR(target_fabric_port_, alua_tg_pt_gp); 607CONFIGFS_ATTR(target_fabric_port_, alua_tg_pt_offline); 608CONFIGFS_ATTR(target_fabric_port_, alua_tg_pt_status); 609CONFIGFS_ATTR(target_fabric_port_, alua_tg_pt_write_md); 610 611static 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 619static 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; 669out: 670 return ret; 671} 672 673static 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 694static 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 702static 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 708TF_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 714static 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 721static void target_core_port_stat_rmdir( 722 struct config_group *group, 723 struct config_item *item) 724{ 725 return; 726} 727 728static 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 733TF_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 739static 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 776static 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 789static 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 794TF_CIT_SETUP(tpg_lun, NULL, &target_fabric_lun_group_ops, NULL); 795 796/* End of tfc_tpg_lun_cit */ 797 798TF_CIT_SETUP_DRV(tpg_attrib, NULL, NULL); 799TF_CIT_SETUP_DRV(tpg_auth, NULL, NULL); 800TF_CIT_SETUP_DRV(tpg_param, NULL, NULL); 801 802/* Start of tfc_tpg_base_cit */ 803 804static 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 814static struct configfs_item_operations target_fabric_tpg_base_item_ops = { 815 .release = target_fabric_tpg_release, 816}; 817 818static 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 824static 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 848CONFIGFS_ATTR(target_fabric_tpg_base_, enable); 849 850static int 851target_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 880done: 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 892static 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 945static 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 956static 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 967static struct configfs_item_operations target_fabric_tpg_item_ops = { 968 .release = target_fabric_release_wwn, 969}; 970 971static 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 976TF_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 */ 986TF_CIT_SETUP(wwn_fabric_stats, NULL, NULL, NULL); 987 988/* End of tfc_wwn_fabric_stats_cit */ 989 990static ssize_t 991target_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 1001static ssize_t 1002target_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} 1032CONFIGFS_ATTR(target_fabric_wwn_, cmd_completion_affinity); 1033 1034static struct configfs_attribute *target_fabric_wwn_param_attrs[] = { 1035 &target_fabric_wwn_attr_cmd_completion_affinity, 1036 NULL, 1037}; 1038 1039TF_CIT_SETUP(wwn_param, NULL, NULL, target_fabric_wwn_param_attrs); 1040 1041/* Start of tfc_wwn_cit */ 1042 1043static 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 1078static 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 1089static 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 1094TF_CIT_SETUP_DRV(wwn, NULL, &target_fabric_wwn_group_ops); 1095TF_CIT_SETUP_DRV(discovery, NULL, NULL); 1096 1097int 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}