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