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