1 /* 2 * Configfs interface for the NVMe target. 3 * Copyright (c) 2015-2016 HGST, a Western Digital Company. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms and conditions of the GNU General Public License, 7 * version 2, as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 */ 14 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 15 #include <linux/kernel.h> 16 #include <linux/module.h> 17 #include <linux/slab.h> 18 #include <linux/stat.h> 19 #include <linux/ctype.h> 20 21 #include "nvmet.h" 22 23 static struct config_item_type nvmet_host_type; 24 static struct config_item_type nvmet_subsys_type; 25 26 /* 27 * nvmet_port Generic ConfigFS definitions. 28 * Used in any place in the ConfigFS tree that refers to an address. 29 */ 30 static ssize_t nvmet_addr_adrfam_show(struct config_item *item, 31 char *page) 32 { 33 switch (to_nvmet_port(item)->disc_addr.adrfam) { 34 case NVMF_ADDR_FAMILY_IP4: 35 return sprintf(page, "ipv4\n"); 36 case NVMF_ADDR_FAMILY_IP6: 37 return sprintf(page, "ipv6\n"); 38 case NVMF_ADDR_FAMILY_IB: 39 return sprintf(page, "ib\n"); 40 case NVMF_ADDR_FAMILY_FC: 41 return sprintf(page, "fc\n"); 42 default: 43 return sprintf(page, "\n"); 44 } 45 } 46 47 static ssize_t nvmet_addr_adrfam_store(struct config_item *item, 48 const char *page, size_t count) 49 { 50 struct nvmet_port *port = to_nvmet_port(item); 51 52 if (port->enabled) { 53 pr_err("Cannot modify address while enabled\n"); 54 pr_err("Disable the address before modifying\n"); 55 return -EACCES; 56 } 57 58 if (sysfs_streq(page, "ipv4")) { 59 port->disc_addr.adrfam = NVMF_ADDR_FAMILY_IP4; 60 } else if (sysfs_streq(page, "ipv6")) { 61 port->disc_addr.adrfam = NVMF_ADDR_FAMILY_IP6; 62 } else if (sysfs_streq(page, "ib")) { 63 port->disc_addr.adrfam = NVMF_ADDR_FAMILY_IB; 64 } else if (sysfs_streq(page, "fc")) { 65 port->disc_addr.adrfam = NVMF_ADDR_FAMILY_FC; 66 } else { 67 pr_err("Invalid value '%s' for adrfam\n", page); 68 return -EINVAL; 69 } 70 71 return count; 72 } 73 74 CONFIGFS_ATTR(nvmet_, addr_adrfam); 75 76 static ssize_t nvmet_addr_portid_show(struct config_item *item, 77 char *page) 78 { 79 struct nvmet_port *port = to_nvmet_port(item); 80 81 return snprintf(page, PAGE_SIZE, "%d\n", 82 le16_to_cpu(port->disc_addr.portid)); 83 } 84 85 static ssize_t nvmet_addr_portid_store(struct config_item *item, 86 const char *page, size_t count) 87 { 88 struct nvmet_port *port = to_nvmet_port(item); 89 u16 portid = 0; 90 91 if (kstrtou16(page, 0, &portid)) { 92 pr_err("Invalid value '%s' for portid\n", page); 93 return -EINVAL; 94 } 95 96 if (port->enabled) { 97 pr_err("Cannot modify address while enabled\n"); 98 pr_err("Disable the address before modifying\n"); 99 return -EACCES; 100 } 101 port->disc_addr.portid = cpu_to_le16(portid); 102 return count; 103 } 104 105 CONFIGFS_ATTR(nvmet_, addr_portid); 106 107 static ssize_t nvmet_addr_traddr_show(struct config_item *item, 108 char *page) 109 { 110 struct nvmet_port *port = to_nvmet_port(item); 111 112 return snprintf(page, PAGE_SIZE, "%s\n", 113 port->disc_addr.traddr); 114 } 115 116 static ssize_t nvmet_addr_traddr_store(struct config_item *item, 117 const char *page, size_t count) 118 { 119 struct nvmet_port *port = to_nvmet_port(item); 120 121 if (count > NVMF_TRADDR_SIZE) { 122 pr_err("Invalid value '%s' for traddr\n", page); 123 return -EINVAL; 124 } 125 126 if (port->enabled) { 127 pr_err("Cannot modify address while enabled\n"); 128 pr_err("Disable the address before modifying\n"); 129 return -EACCES; 130 } 131 return snprintf(port->disc_addr.traddr, 132 sizeof(port->disc_addr.traddr), "%s", page); 133 } 134 135 CONFIGFS_ATTR(nvmet_, addr_traddr); 136 137 static ssize_t nvmet_addr_treq_show(struct config_item *item, 138 char *page) 139 { 140 switch (to_nvmet_port(item)->disc_addr.treq) { 141 case NVMF_TREQ_NOT_SPECIFIED: 142 return sprintf(page, "not specified\n"); 143 case NVMF_TREQ_REQUIRED: 144 return sprintf(page, "required\n"); 145 case NVMF_TREQ_NOT_REQUIRED: 146 return sprintf(page, "not required\n"); 147 default: 148 return sprintf(page, "\n"); 149 } 150 } 151 152 static ssize_t nvmet_addr_treq_store(struct config_item *item, 153 const char *page, size_t count) 154 { 155 struct nvmet_port *port = to_nvmet_port(item); 156 157 if (port->enabled) { 158 pr_err("Cannot modify address while enabled\n"); 159 pr_err("Disable the address before modifying\n"); 160 return -EACCES; 161 } 162 163 if (sysfs_streq(page, "not specified")) { 164 port->disc_addr.treq = NVMF_TREQ_NOT_SPECIFIED; 165 } else if (sysfs_streq(page, "required")) { 166 port->disc_addr.treq = NVMF_TREQ_REQUIRED; 167 } else if (sysfs_streq(page, "not required")) { 168 port->disc_addr.treq = NVMF_TREQ_NOT_REQUIRED; 169 } else { 170 pr_err("Invalid value '%s' for treq\n", page); 171 return -EINVAL; 172 } 173 174 return count; 175 } 176 177 CONFIGFS_ATTR(nvmet_, addr_treq); 178 179 static ssize_t nvmet_addr_trsvcid_show(struct config_item *item, 180 char *page) 181 { 182 struct nvmet_port *port = to_nvmet_port(item); 183 184 return snprintf(page, PAGE_SIZE, "%s\n", 185 port->disc_addr.trsvcid); 186 } 187 188 static ssize_t nvmet_addr_trsvcid_store(struct config_item *item, 189 const char *page, size_t count) 190 { 191 struct nvmet_port *port = to_nvmet_port(item); 192 193 if (count > NVMF_TRSVCID_SIZE) { 194 pr_err("Invalid value '%s' for trsvcid\n", page); 195 return -EINVAL; 196 } 197 if (port->enabled) { 198 pr_err("Cannot modify address while enabled\n"); 199 pr_err("Disable the address before modifying\n"); 200 return -EACCES; 201 } 202 return snprintf(port->disc_addr.trsvcid, 203 sizeof(port->disc_addr.trsvcid), "%s", page); 204 } 205 206 CONFIGFS_ATTR(nvmet_, addr_trsvcid); 207 208 static ssize_t nvmet_addr_trtype_show(struct config_item *item, 209 char *page) 210 { 211 switch (to_nvmet_port(item)->disc_addr.trtype) { 212 case NVMF_TRTYPE_RDMA: 213 return sprintf(page, "rdma\n"); 214 case NVMF_TRTYPE_LOOP: 215 return sprintf(page, "loop\n"); 216 case NVMF_TRTYPE_FC: 217 return sprintf(page, "fc\n"); 218 default: 219 return sprintf(page, "\n"); 220 } 221 } 222 223 static void nvmet_port_init_tsas_rdma(struct nvmet_port *port) 224 { 225 port->disc_addr.trtype = NVMF_TRTYPE_RDMA; 226 memset(&port->disc_addr.tsas.rdma, 0, NVMF_TSAS_SIZE); 227 port->disc_addr.tsas.rdma.qptype = NVMF_RDMA_QPTYPE_CONNECTED; 228 port->disc_addr.tsas.rdma.prtype = NVMF_RDMA_PRTYPE_NOT_SPECIFIED; 229 port->disc_addr.tsas.rdma.cms = NVMF_RDMA_CMS_RDMA_CM; 230 } 231 232 static void nvmet_port_init_tsas_loop(struct nvmet_port *port) 233 { 234 port->disc_addr.trtype = NVMF_TRTYPE_LOOP; 235 memset(&port->disc_addr.tsas, 0, NVMF_TSAS_SIZE); 236 } 237 238 static void nvmet_port_init_tsas_fc(struct nvmet_port *port) 239 { 240 port->disc_addr.trtype = NVMF_TRTYPE_FC; 241 memset(&port->disc_addr.tsas, 0, NVMF_TSAS_SIZE); 242 } 243 244 static ssize_t nvmet_addr_trtype_store(struct config_item *item, 245 const char *page, size_t count) 246 { 247 struct nvmet_port *port = to_nvmet_port(item); 248 249 if (port->enabled) { 250 pr_err("Cannot modify address while enabled\n"); 251 pr_err("Disable the address before modifying\n"); 252 return -EACCES; 253 } 254 255 if (sysfs_streq(page, "rdma")) { 256 nvmet_port_init_tsas_rdma(port); 257 } else if (sysfs_streq(page, "loop")) { 258 nvmet_port_init_tsas_loop(port); 259 } else if (sysfs_streq(page, "fc")) { 260 nvmet_port_init_tsas_fc(port); 261 } else { 262 pr_err("Invalid value '%s' for trtype\n", page); 263 return -EINVAL; 264 } 265 266 return count; 267 } 268 269 CONFIGFS_ATTR(nvmet_, addr_trtype); 270 271 /* 272 * Namespace structures & file operation functions below 273 */ 274 static ssize_t nvmet_ns_device_path_show(struct config_item *item, char *page) 275 { 276 return sprintf(page, "%s\n", to_nvmet_ns(item)->device_path); 277 } 278 279 static ssize_t nvmet_ns_device_path_store(struct config_item *item, 280 const char *page, size_t count) 281 { 282 struct nvmet_ns *ns = to_nvmet_ns(item); 283 struct nvmet_subsys *subsys = ns->subsys; 284 int ret; 285 286 mutex_lock(&subsys->lock); 287 ret = -EBUSY; 288 if (ns->enabled) 289 goto out_unlock; 290 291 kfree(ns->device_path); 292 293 ret = -ENOMEM; 294 ns->device_path = kstrdup(page, GFP_KERNEL); 295 if (!ns->device_path) 296 goto out_unlock; 297 298 mutex_unlock(&subsys->lock); 299 return count; 300 301 out_unlock: 302 mutex_unlock(&subsys->lock); 303 return ret; 304 } 305 306 CONFIGFS_ATTR(nvmet_ns_, device_path); 307 308 static ssize_t nvmet_ns_device_nguid_show(struct config_item *item, char *page) 309 { 310 return sprintf(page, "%pUb\n", &to_nvmet_ns(item)->nguid); 311 } 312 313 static ssize_t nvmet_ns_device_nguid_store(struct config_item *item, 314 const char *page, size_t count) 315 { 316 struct nvmet_ns *ns = to_nvmet_ns(item); 317 struct nvmet_subsys *subsys = ns->subsys; 318 u8 nguid[16]; 319 const char *p = page; 320 int i; 321 int ret = 0; 322 323 mutex_lock(&subsys->lock); 324 if (ns->enabled) { 325 ret = -EBUSY; 326 goto out_unlock; 327 } 328 329 for (i = 0; i < 16; i++) { 330 if (p + 2 > page + count) { 331 ret = -EINVAL; 332 goto out_unlock; 333 } 334 if (!isxdigit(p[0]) || !isxdigit(p[1])) { 335 ret = -EINVAL; 336 goto out_unlock; 337 } 338 339 nguid[i] = (hex_to_bin(p[0]) << 4) | hex_to_bin(p[1]); 340 p += 2; 341 342 if (*p == '-' || *p == ':') 343 p++; 344 } 345 346 memcpy(&ns->nguid, nguid, sizeof(nguid)); 347 out_unlock: 348 mutex_unlock(&subsys->lock); 349 return ret ? ret : count; 350 } 351 352 CONFIGFS_ATTR(nvmet_ns_, device_nguid); 353 354 static ssize_t nvmet_ns_enable_show(struct config_item *item, char *page) 355 { 356 return sprintf(page, "%d\n", to_nvmet_ns(item)->enabled); 357 } 358 359 static ssize_t nvmet_ns_enable_store(struct config_item *item, 360 const char *page, size_t count) 361 { 362 struct nvmet_ns *ns = to_nvmet_ns(item); 363 bool enable; 364 int ret = 0; 365 366 if (strtobool(page, &enable)) 367 return -EINVAL; 368 369 if (enable) 370 ret = nvmet_ns_enable(ns); 371 else 372 nvmet_ns_disable(ns); 373 374 return ret ? ret : count; 375 } 376 377 CONFIGFS_ATTR(nvmet_ns_, enable); 378 379 static struct configfs_attribute *nvmet_ns_attrs[] = { 380 &nvmet_ns_attr_device_path, 381 &nvmet_ns_attr_device_nguid, 382 &nvmet_ns_attr_enable, 383 NULL, 384 }; 385 386 static void nvmet_ns_release(struct config_item *item) 387 { 388 struct nvmet_ns *ns = to_nvmet_ns(item); 389 390 nvmet_ns_free(ns); 391 } 392 393 static struct configfs_item_operations nvmet_ns_item_ops = { 394 .release = nvmet_ns_release, 395 }; 396 397 static struct config_item_type nvmet_ns_type = { 398 .ct_item_ops = &nvmet_ns_item_ops, 399 .ct_attrs = nvmet_ns_attrs, 400 .ct_owner = THIS_MODULE, 401 }; 402 403 static struct config_group *nvmet_ns_make(struct config_group *group, 404 const char *name) 405 { 406 struct nvmet_subsys *subsys = namespaces_to_subsys(&group->cg_item); 407 struct nvmet_ns *ns; 408 int ret; 409 u32 nsid; 410 411 ret = kstrtou32(name, 0, &nsid); 412 if (ret) 413 goto out; 414 415 ret = -EINVAL; 416 if (nsid == 0 || nsid == 0xffffffff) 417 goto out; 418 419 ret = -ENOMEM; 420 ns = nvmet_ns_alloc(subsys, nsid); 421 if (!ns) 422 goto out; 423 config_group_init_type_name(&ns->group, name, &nvmet_ns_type); 424 425 pr_info("adding nsid %d to subsystem %s\n", nsid, subsys->subsysnqn); 426 427 return &ns->group; 428 out: 429 return ERR_PTR(ret); 430 } 431 432 static struct configfs_group_operations nvmet_namespaces_group_ops = { 433 .make_group = nvmet_ns_make, 434 }; 435 436 static struct config_item_type nvmet_namespaces_type = { 437 .ct_group_ops = &nvmet_namespaces_group_ops, 438 .ct_owner = THIS_MODULE, 439 }; 440 441 static int nvmet_port_subsys_allow_link(struct config_item *parent, 442 struct config_item *target) 443 { 444 struct nvmet_port *port = to_nvmet_port(parent->ci_parent); 445 struct nvmet_subsys *subsys; 446 struct nvmet_subsys_link *link, *p; 447 int ret; 448 449 if (target->ci_type != &nvmet_subsys_type) { 450 pr_err("can only link subsystems into the subsystems dir.!\n"); 451 return -EINVAL; 452 } 453 subsys = to_subsys(target); 454 link = kmalloc(sizeof(*link), GFP_KERNEL); 455 if (!link) 456 return -ENOMEM; 457 link->subsys = subsys; 458 459 down_write(&nvmet_config_sem); 460 ret = -EEXIST; 461 list_for_each_entry(p, &port->subsystems, entry) { 462 if (p->subsys == subsys) 463 goto out_free_link; 464 } 465 466 if (list_empty(&port->subsystems)) { 467 ret = nvmet_enable_port(port); 468 if (ret) 469 goto out_free_link; 470 } 471 472 list_add_tail(&link->entry, &port->subsystems); 473 nvmet_genctr++; 474 up_write(&nvmet_config_sem); 475 return 0; 476 477 out_free_link: 478 up_write(&nvmet_config_sem); 479 kfree(link); 480 return ret; 481 } 482 483 static void nvmet_port_subsys_drop_link(struct config_item *parent, 484 struct config_item *target) 485 { 486 struct nvmet_port *port = to_nvmet_port(parent->ci_parent); 487 struct nvmet_subsys *subsys = to_subsys(target); 488 struct nvmet_subsys_link *p; 489 490 down_write(&nvmet_config_sem); 491 list_for_each_entry(p, &port->subsystems, entry) { 492 if (p->subsys == subsys) 493 goto found; 494 } 495 up_write(&nvmet_config_sem); 496 return; 497 498 found: 499 list_del(&p->entry); 500 nvmet_genctr++; 501 if (list_empty(&port->subsystems)) 502 nvmet_disable_port(port); 503 up_write(&nvmet_config_sem); 504 kfree(p); 505 } 506 507 static struct configfs_item_operations nvmet_port_subsys_item_ops = { 508 .allow_link = nvmet_port_subsys_allow_link, 509 .drop_link = nvmet_port_subsys_drop_link, 510 }; 511 512 static struct config_item_type nvmet_port_subsys_type = { 513 .ct_item_ops = &nvmet_port_subsys_item_ops, 514 .ct_owner = THIS_MODULE, 515 }; 516 517 static int nvmet_allowed_hosts_allow_link(struct config_item *parent, 518 struct config_item *target) 519 { 520 struct nvmet_subsys *subsys = to_subsys(parent->ci_parent); 521 struct nvmet_host *host; 522 struct nvmet_host_link *link, *p; 523 int ret; 524 525 if (target->ci_type != &nvmet_host_type) { 526 pr_err("can only link hosts into the allowed_hosts directory!\n"); 527 return -EINVAL; 528 } 529 530 host = to_host(target); 531 link = kmalloc(sizeof(*link), GFP_KERNEL); 532 if (!link) 533 return -ENOMEM; 534 link->host = host; 535 536 down_write(&nvmet_config_sem); 537 ret = -EINVAL; 538 if (subsys->allow_any_host) { 539 pr_err("can't add hosts when allow_any_host is set!\n"); 540 goto out_free_link; 541 } 542 543 ret = -EEXIST; 544 list_for_each_entry(p, &subsys->hosts, entry) { 545 if (!strcmp(nvmet_host_name(p->host), nvmet_host_name(host))) 546 goto out_free_link; 547 } 548 list_add_tail(&link->entry, &subsys->hosts); 549 nvmet_genctr++; 550 up_write(&nvmet_config_sem); 551 return 0; 552 out_free_link: 553 up_write(&nvmet_config_sem); 554 kfree(link); 555 return ret; 556 } 557 558 static void nvmet_allowed_hosts_drop_link(struct config_item *parent, 559 struct config_item *target) 560 { 561 struct nvmet_subsys *subsys = to_subsys(parent->ci_parent); 562 struct nvmet_host *host = to_host(target); 563 struct nvmet_host_link *p; 564 565 down_write(&nvmet_config_sem); 566 list_for_each_entry(p, &subsys->hosts, entry) { 567 if (!strcmp(nvmet_host_name(p->host), nvmet_host_name(host))) 568 goto found; 569 } 570 up_write(&nvmet_config_sem); 571 return; 572 573 found: 574 list_del(&p->entry); 575 nvmet_genctr++; 576 up_write(&nvmet_config_sem); 577 kfree(p); 578 } 579 580 static struct configfs_item_operations nvmet_allowed_hosts_item_ops = { 581 .allow_link = nvmet_allowed_hosts_allow_link, 582 .drop_link = nvmet_allowed_hosts_drop_link, 583 }; 584 585 static struct config_item_type nvmet_allowed_hosts_type = { 586 .ct_item_ops = &nvmet_allowed_hosts_item_ops, 587 .ct_owner = THIS_MODULE, 588 }; 589 590 static ssize_t nvmet_subsys_attr_allow_any_host_show(struct config_item *item, 591 char *page) 592 { 593 return snprintf(page, PAGE_SIZE, "%d\n", 594 to_subsys(item)->allow_any_host); 595 } 596 597 static ssize_t nvmet_subsys_attr_allow_any_host_store(struct config_item *item, 598 const char *page, size_t count) 599 { 600 struct nvmet_subsys *subsys = to_subsys(item); 601 bool allow_any_host; 602 int ret = 0; 603 604 if (strtobool(page, &allow_any_host)) 605 return -EINVAL; 606 607 down_write(&nvmet_config_sem); 608 if (allow_any_host && !list_empty(&subsys->hosts)) { 609 pr_err("Can't set allow_any_host when explicit hosts are set!\n"); 610 ret = -EINVAL; 611 goto out_unlock; 612 } 613 614 subsys->allow_any_host = allow_any_host; 615 out_unlock: 616 up_write(&nvmet_config_sem); 617 return ret ? ret : count; 618 } 619 620 CONFIGFS_ATTR(nvmet_subsys_, attr_allow_any_host); 621 622 static struct configfs_attribute *nvmet_subsys_attrs[] = { 623 &nvmet_subsys_attr_attr_allow_any_host, 624 NULL, 625 }; 626 627 /* 628 * Subsystem structures & folder operation functions below 629 */ 630 static void nvmet_subsys_release(struct config_item *item) 631 { 632 struct nvmet_subsys *subsys = to_subsys(item); 633 634 nvmet_subsys_del_ctrls(subsys); 635 nvmet_subsys_put(subsys); 636 } 637 638 static struct configfs_item_operations nvmet_subsys_item_ops = { 639 .release = nvmet_subsys_release, 640 }; 641 642 static struct config_item_type nvmet_subsys_type = { 643 .ct_item_ops = &nvmet_subsys_item_ops, 644 .ct_attrs = nvmet_subsys_attrs, 645 .ct_owner = THIS_MODULE, 646 }; 647 648 static struct config_group *nvmet_subsys_make(struct config_group *group, 649 const char *name) 650 { 651 struct nvmet_subsys *subsys; 652 653 if (sysfs_streq(name, NVME_DISC_SUBSYS_NAME)) { 654 pr_err("can't create discovery subsystem through configfs\n"); 655 return ERR_PTR(-EINVAL); 656 } 657 658 subsys = nvmet_subsys_alloc(name, NVME_NQN_NVME); 659 if (!subsys) 660 return ERR_PTR(-ENOMEM); 661 662 config_group_init_type_name(&subsys->group, name, &nvmet_subsys_type); 663 664 config_group_init_type_name(&subsys->namespaces_group, 665 "namespaces", &nvmet_namespaces_type); 666 configfs_add_default_group(&subsys->namespaces_group, &subsys->group); 667 668 config_group_init_type_name(&subsys->allowed_hosts_group, 669 "allowed_hosts", &nvmet_allowed_hosts_type); 670 configfs_add_default_group(&subsys->allowed_hosts_group, 671 &subsys->group); 672 673 return &subsys->group; 674 } 675 676 static struct configfs_group_operations nvmet_subsystems_group_ops = { 677 .make_group = nvmet_subsys_make, 678 }; 679 680 static struct config_item_type nvmet_subsystems_type = { 681 .ct_group_ops = &nvmet_subsystems_group_ops, 682 .ct_owner = THIS_MODULE, 683 }; 684 685 static ssize_t nvmet_referral_enable_show(struct config_item *item, 686 char *page) 687 { 688 return snprintf(page, PAGE_SIZE, "%d\n", to_nvmet_port(item)->enabled); 689 } 690 691 static ssize_t nvmet_referral_enable_store(struct config_item *item, 692 const char *page, size_t count) 693 { 694 struct nvmet_port *parent = to_nvmet_port(item->ci_parent->ci_parent); 695 struct nvmet_port *port = to_nvmet_port(item); 696 bool enable; 697 698 if (strtobool(page, &enable)) 699 goto inval; 700 701 if (enable) 702 nvmet_referral_enable(parent, port); 703 else 704 nvmet_referral_disable(port); 705 706 return count; 707 inval: 708 pr_err("Invalid value '%s' for enable\n", page); 709 return -EINVAL; 710 } 711 712 CONFIGFS_ATTR(nvmet_referral_, enable); 713 714 /* 715 * Discovery Service subsystem definitions 716 */ 717 static struct configfs_attribute *nvmet_referral_attrs[] = { 718 &nvmet_attr_addr_adrfam, 719 &nvmet_attr_addr_portid, 720 &nvmet_attr_addr_treq, 721 &nvmet_attr_addr_traddr, 722 &nvmet_attr_addr_trsvcid, 723 &nvmet_attr_addr_trtype, 724 &nvmet_referral_attr_enable, 725 NULL, 726 }; 727 728 static void nvmet_referral_release(struct config_item *item) 729 { 730 struct nvmet_port *port = to_nvmet_port(item); 731 732 nvmet_referral_disable(port); 733 kfree(port); 734 } 735 736 static struct configfs_item_operations nvmet_referral_item_ops = { 737 .release = nvmet_referral_release, 738 }; 739 740 static struct config_item_type nvmet_referral_type = { 741 .ct_owner = THIS_MODULE, 742 .ct_attrs = nvmet_referral_attrs, 743 .ct_item_ops = &nvmet_referral_item_ops, 744 }; 745 746 static struct config_group *nvmet_referral_make( 747 struct config_group *group, const char *name) 748 { 749 struct nvmet_port *port; 750 751 port = kzalloc(sizeof(*port), GFP_KERNEL); 752 if (!port) 753 return ERR_PTR(-ENOMEM); 754 755 INIT_LIST_HEAD(&port->entry); 756 config_group_init_type_name(&port->group, name, &nvmet_referral_type); 757 758 return &port->group; 759 } 760 761 static struct configfs_group_operations nvmet_referral_group_ops = { 762 .make_group = nvmet_referral_make, 763 }; 764 765 static struct config_item_type nvmet_referrals_type = { 766 .ct_owner = THIS_MODULE, 767 .ct_group_ops = &nvmet_referral_group_ops, 768 }; 769 770 /* 771 * Ports definitions. 772 */ 773 static void nvmet_port_release(struct config_item *item) 774 { 775 struct nvmet_port *port = to_nvmet_port(item); 776 777 kfree(port); 778 } 779 780 static struct configfs_attribute *nvmet_port_attrs[] = { 781 &nvmet_attr_addr_adrfam, 782 &nvmet_attr_addr_treq, 783 &nvmet_attr_addr_traddr, 784 &nvmet_attr_addr_trsvcid, 785 &nvmet_attr_addr_trtype, 786 NULL, 787 }; 788 789 static struct configfs_item_operations nvmet_port_item_ops = { 790 .release = nvmet_port_release, 791 }; 792 793 static struct config_item_type nvmet_port_type = { 794 .ct_attrs = nvmet_port_attrs, 795 .ct_item_ops = &nvmet_port_item_ops, 796 .ct_owner = THIS_MODULE, 797 }; 798 799 static struct config_group *nvmet_ports_make(struct config_group *group, 800 const char *name) 801 { 802 struct nvmet_port *port; 803 u16 portid; 804 805 if (kstrtou16(name, 0, &portid)) 806 return ERR_PTR(-EINVAL); 807 808 port = kzalloc(sizeof(*port), GFP_KERNEL); 809 if (!port) 810 return ERR_PTR(-ENOMEM); 811 812 INIT_LIST_HEAD(&port->entry); 813 INIT_LIST_HEAD(&port->subsystems); 814 INIT_LIST_HEAD(&port->referrals); 815 816 port->disc_addr.portid = cpu_to_le16(portid); 817 config_group_init_type_name(&port->group, name, &nvmet_port_type); 818 819 config_group_init_type_name(&port->subsys_group, 820 "subsystems", &nvmet_port_subsys_type); 821 configfs_add_default_group(&port->subsys_group, &port->group); 822 823 config_group_init_type_name(&port->referrals_group, 824 "referrals", &nvmet_referrals_type); 825 configfs_add_default_group(&port->referrals_group, &port->group); 826 827 return &port->group; 828 } 829 830 static struct configfs_group_operations nvmet_ports_group_ops = { 831 .make_group = nvmet_ports_make, 832 }; 833 834 static struct config_item_type nvmet_ports_type = { 835 .ct_group_ops = &nvmet_ports_group_ops, 836 .ct_owner = THIS_MODULE, 837 }; 838 839 static struct config_group nvmet_subsystems_group; 840 static struct config_group nvmet_ports_group; 841 842 static void nvmet_host_release(struct config_item *item) 843 { 844 struct nvmet_host *host = to_host(item); 845 846 kfree(host); 847 } 848 849 static struct configfs_item_operations nvmet_host_item_ops = { 850 .release = nvmet_host_release, 851 }; 852 853 static struct config_item_type nvmet_host_type = { 854 .ct_item_ops = &nvmet_host_item_ops, 855 .ct_owner = THIS_MODULE, 856 }; 857 858 static struct config_group *nvmet_hosts_make_group(struct config_group *group, 859 const char *name) 860 { 861 struct nvmet_host *host; 862 863 host = kzalloc(sizeof(*host), GFP_KERNEL); 864 if (!host) 865 return ERR_PTR(-ENOMEM); 866 867 config_group_init_type_name(&host->group, name, &nvmet_host_type); 868 869 return &host->group; 870 } 871 872 static struct configfs_group_operations nvmet_hosts_group_ops = { 873 .make_group = nvmet_hosts_make_group, 874 }; 875 876 static struct config_item_type nvmet_hosts_type = { 877 .ct_group_ops = &nvmet_hosts_group_ops, 878 .ct_owner = THIS_MODULE, 879 }; 880 881 static struct config_group nvmet_hosts_group; 882 883 static struct config_item_type nvmet_root_type = { 884 .ct_owner = THIS_MODULE, 885 }; 886 887 static struct configfs_subsystem nvmet_configfs_subsystem = { 888 .su_group = { 889 .cg_item = { 890 .ci_namebuf = "nvmet", 891 .ci_type = &nvmet_root_type, 892 }, 893 }, 894 }; 895 896 int __init nvmet_init_configfs(void) 897 { 898 int ret; 899 900 config_group_init(&nvmet_configfs_subsystem.su_group); 901 mutex_init(&nvmet_configfs_subsystem.su_mutex); 902 903 config_group_init_type_name(&nvmet_subsystems_group, 904 "subsystems", &nvmet_subsystems_type); 905 configfs_add_default_group(&nvmet_subsystems_group, 906 &nvmet_configfs_subsystem.su_group); 907 908 config_group_init_type_name(&nvmet_ports_group, 909 "ports", &nvmet_ports_type); 910 configfs_add_default_group(&nvmet_ports_group, 911 &nvmet_configfs_subsystem.su_group); 912 913 config_group_init_type_name(&nvmet_hosts_group, 914 "hosts", &nvmet_hosts_type); 915 configfs_add_default_group(&nvmet_hosts_group, 916 &nvmet_configfs_subsystem.su_group); 917 918 ret = configfs_register_subsystem(&nvmet_configfs_subsystem); 919 if (ret) { 920 pr_err("configfs_register_subsystem: %d\n", ret); 921 return ret; 922 } 923 924 return 0; 925 } 926 927 void __exit nvmet_exit_configfs(void) 928 { 929 configfs_unregister_subsystem(&nvmet_configfs_subsystem); 930 } 931