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