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