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