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