2 * Configfs interface for the NVMe target.
3 * Copyright (c) 2015-2016 HGST, a Western Digital Company.
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.
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
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>
23 static const struct config_item_type nvmet_host_type;
24 static const struct config_item_type nvmet_subsys_type;
26 static const struct nvmet_transport_name {
29 } nvmet_transport_names[] = {
30 { NVMF_TRTYPE_RDMA, "rdma" },
31 { NVMF_TRTYPE_FC, "fc" },
32 { NVMF_TRTYPE_LOOP, "loop" },
36 * nvmet_port Generic ConfigFS definitions.
37 * Used in any place in the ConfigFS tree that refers to an address.
39 static ssize_t nvmet_addr_adrfam_show(struct config_item *item,
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");
52 return sprintf(page, "\n");
56 static ssize_t nvmet_addr_adrfam_store(struct config_item *item,
57 const char *page, size_t count)
59 struct nvmet_port *port = to_nvmet_port(item);
62 pr_err("Cannot modify address while enabled\n");
63 pr_err("Disable the address before modifying\n");
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;
76 pr_err("Invalid value '%s' for adrfam\n", page);
83 CONFIGFS_ATTR(nvmet_, addr_adrfam);
85 static ssize_t nvmet_addr_portid_show(struct config_item *item,
88 struct nvmet_port *port = to_nvmet_port(item);
90 return snprintf(page, PAGE_SIZE, "%d\n",
91 le16_to_cpu(port->disc_addr.portid));
94 static ssize_t nvmet_addr_portid_store(struct config_item *item,
95 const char *page, size_t count)
97 struct nvmet_port *port = to_nvmet_port(item);
100 if (kstrtou16(page, 0, &portid)) {
101 pr_err("Invalid value '%s' for portid\n", page);
106 pr_err("Cannot modify address while enabled\n");
107 pr_err("Disable the address before modifying\n");
110 port->disc_addr.portid = cpu_to_le16(portid);
114 CONFIGFS_ATTR(nvmet_, addr_portid);
116 static ssize_t nvmet_addr_traddr_show(struct config_item *item,
119 struct nvmet_port *port = to_nvmet_port(item);
121 return snprintf(page, PAGE_SIZE, "%s\n",
122 port->disc_addr.traddr);
125 static ssize_t nvmet_addr_traddr_store(struct config_item *item,
126 const char *page, size_t count)
128 struct nvmet_port *port = to_nvmet_port(item);
130 if (count > NVMF_TRADDR_SIZE) {
131 pr_err("Invalid value '%s' for traddr\n", page);
136 pr_err("Cannot modify address while enabled\n");
137 pr_err("Disable the address before modifying\n");
141 if (sscanf(page, "%s\n", port->disc_addr.traddr) != 1)
146 CONFIGFS_ATTR(nvmet_, addr_traddr);
148 static ssize_t nvmet_addr_treq_show(struct config_item *item,
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");
159 return sprintf(page, "\n");
163 static ssize_t nvmet_addr_treq_store(struct config_item *item,
164 const char *page, size_t count)
166 struct nvmet_port *port = to_nvmet_port(item);
169 pr_err("Cannot modify address while enabled\n");
170 pr_err("Disable the address before modifying\n");
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;
181 pr_err("Invalid value '%s' for treq\n", page);
188 CONFIGFS_ATTR(nvmet_, addr_treq);
190 static ssize_t nvmet_addr_trsvcid_show(struct config_item *item,
193 struct nvmet_port *port = to_nvmet_port(item);
195 return snprintf(page, PAGE_SIZE, "%s\n",
196 port->disc_addr.trsvcid);
199 static ssize_t nvmet_addr_trsvcid_store(struct config_item *item,
200 const char *page, size_t count)
202 struct nvmet_port *port = to_nvmet_port(item);
204 if (count > NVMF_TRSVCID_SIZE) {
205 pr_err("Invalid value '%s' for trsvcid\n", page);
209 pr_err("Cannot modify address while enabled\n");
210 pr_err("Disable the address before modifying\n");
214 if (sscanf(page, "%s\n", port->disc_addr.trsvcid) != 1)
219 CONFIGFS_ATTR(nvmet_, addr_trsvcid);
221 static ssize_t nvmet_param_inline_data_size_show(struct config_item *item,
224 struct nvmet_port *port = to_nvmet_port(item);
226 return snprintf(page, PAGE_SIZE, "%d\n", port->inline_data_size);
229 static ssize_t nvmet_param_inline_data_size_store(struct config_item *item,
230 const char *page, size_t count)
232 struct nvmet_port *port = to_nvmet_port(item);
236 pr_err("Cannot modify inline_data_size while port enabled\n");
237 pr_err("Disable the port before modifying\n");
240 ret = kstrtoint(page, 0, &port->inline_data_size);
242 pr_err("Invalid value '%s' for inline_data_size\n", page);
248 CONFIGFS_ATTR(nvmet_, param_inline_data_size);
250 static ssize_t nvmet_addr_trtype_show(struct config_item *item,
253 struct nvmet_port *port = to_nvmet_port(item);
256 for (i = 0; i < ARRAY_SIZE(nvmet_transport_names); i++) {
257 if (port->disc_addr.trtype != nvmet_transport_names[i].type)
259 return sprintf(page, "%s\n", nvmet_transport_names[i].name);
262 return sprintf(page, "\n");
265 static void nvmet_port_init_tsas_rdma(struct nvmet_port *port)
267 port->disc_addr.tsas.rdma.qptype = NVMF_RDMA_QPTYPE_CONNECTED;
268 port->disc_addr.tsas.rdma.prtype = NVMF_RDMA_PRTYPE_NOT_SPECIFIED;
269 port->disc_addr.tsas.rdma.cms = NVMF_RDMA_CMS_RDMA_CM;
272 static ssize_t nvmet_addr_trtype_store(struct config_item *item,
273 const char *page, size_t count)
275 struct nvmet_port *port = to_nvmet_port(item);
279 pr_err("Cannot modify address while enabled\n");
280 pr_err("Disable the address before modifying\n");
284 for (i = 0; i < ARRAY_SIZE(nvmet_transport_names); i++) {
285 if (sysfs_streq(page, nvmet_transport_names[i].name))
289 pr_err("Invalid value '%s' for trtype\n", page);
292 memset(&port->disc_addr.tsas, 0, NVMF_TSAS_SIZE);
293 port->disc_addr.trtype = nvmet_transport_names[i].type;
294 if (port->disc_addr.trtype == NVMF_TRTYPE_RDMA)
295 nvmet_port_init_tsas_rdma(port);
299 CONFIGFS_ATTR(nvmet_, addr_trtype);
302 * Namespace structures & file operation functions below
304 static ssize_t nvmet_ns_device_path_show(struct config_item *item, char *page)
306 return sprintf(page, "%s\n", to_nvmet_ns(item)->device_path);
309 static ssize_t nvmet_ns_device_path_store(struct config_item *item,
310 const char *page, size_t count)
312 struct nvmet_ns *ns = to_nvmet_ns(item);
313 struct nvmet_subsys *subsys = ns->subsys;
316 mutex_lock(&subsys->lock);
321 kfree(ns->device_path);
324 ns->device_path = kstrndup(page, strcspn(page, "\n"), GFP_KERNEL);
325 if (!ns->device_path)
328 mutex_unlock(&subsys->lock);
332 mutex_unlock(&subsys->lock);
336 CONFIGFS_ATTR(nvmet_ns_, device_path);
338 static ssize_t nvmet_ns_device_uuid_show(struct config_item *item, char *page)
340 return sprintf(page, "%pUb\n", &to_nvmet_ns(item)->uuid);
343 static ssize_t nvmet_ns_device_uuid_store(struct config_item *item,
344 const char *page, size_t count)
346 struct nvmet_ns *ns = to_nvmet_ns(item);
347 struct nvmet_subsys *subsys = ns->subsys;
351 mutex_lock(&subsys->lock);
358 if (uuid_parse(page, &ns->uuid))
362 mutex_unlock(&subsys->lock);
363 return ret ? ret : count;
366 CONFIGFS_ATTR(nvmet_ns_, device_uuid);
368 static ssize_t nvmet_ns_device_nguid_show(struct config_item *item, char *page)
370 return sprintf(page, "%pUb\n", &to_nvmet_ns(item)->nguid);
373 static ssize_t nvmet_ns_device_nguid_store(struct config_item *item,
374 const char *page, size_t count)
376 struct nvmet_ns *ns = to_nvmet_ns(item);
377 struct nvmet_subsys *subsys = ns->subsys;
379 const char *p = page;
383 mutex_lock(&subsys->lock);
389 for (i = 0; i < 16; i++) {
390 if (p + 2 > page + count) {
394 if (!isxdigit(p[0]) || !isxdigit(p[1])) {
399 nguid[i] = (hex_to_bin(p[0]) << 4) | hex_to_bin(p[1]);
402 if (*p == '-' || *p == ':')
406 memcpy(&ns->nguid, nguid, sizeof(nguid));
408 mutex_unlock(&subsys->lock);
409 return ret ? ret : count;
412 CONFIGFS_ATTR(nvmet_ns_, device_nguid);
414 static ssize_t nvmet_ns_enable_show(struct config_item *item, char *page)
416 return sprintf(page, "%d\n", to_nvmet_ns(item)->enabled);
419 static ssize_t nvmet_ns_enable_store(struct config_item *item,
420 const char *page, size_t count)
422 struct nvmet_ns *ns = to_nvmet_ns(item);
426 if (strtobool(page, &enable))
430 ret = nvmet_ns_enable(ns);
432 nvmet_ns_disable(ns);
434 return ret ? ret : count;
437 CONFIGFS_ATTR(nvmet_ns_, enable);
439 static ssize_t nvmet_ns_buffered_io_show(struct config_item *item, char *page)
441 return sprintf(page, "%d\n", to_nvmet_ns(item)->buffered_io);
444 static ssize_t nvmet_ns_buffered_io_store(struct config_item *item,
445 const char *page, size_t count)
447 struct nvmet_ns *ns = to_nvmet_ns(item);
450 if (strtobool(page, &val))
453 mutex_lock(&ns->subsys->lock);
455 pr_err("disable ns before setting buffered_io value.\n");
456 mutex_unlock(&ns->subsys->lock);
460 ns->buffered_io = val;
461 mutex_unlock(&ns->subsys->lock);
465 CONFIGFS_ATTR(nvmet_ns_, buffered_io);
467 static struct configfs_attribute *nvmet_ns_attrs[] = {
468 &nvmet_ns_attr_device_path,
469 &nvmet_ns_attr_device_nguid,
470 &nvmet_ns_attr_device_uuid,
471 &nvmet_ns_attr_enable,
472 &nvmet_ns_attr_buffered_io,
476 static void nvmet_ns_release(struct config_item *item)
478 struct nvmet_ns *ns = to_nvmet_ns(item);
483 static struct configfs_item_operations nvmet_ns_item_ops = {
484 .release = nvmet_ns_release,
487 static const struct config_item_type nvmet_ns_type = {
488 .ct_item_ops = &nvmet_ns_item_ops,
489 .ct_attrs = nvmet_ns_attrs,
490 .ct_owner = THIS_MODULE,
493 static struct config_group *nvmet_ns_make(struct config_group *group,
496 struct nvmet_subsys *subsys = namespaces_to_subsys(&group->cg_item);
501 ret = kstrtou32(name, 0, &nsid);
506 if (nsid == 0 || nsid == NVME_NSID_ALL)
510 ns = nvmet_ns_alloc(subsys, nsid);
513 config_group_init_type_name(&ns->group, name, &nvmet_ns_type);
515 pr_info("adding nsid %d to subsystem %s\n", nsid, subsys->subsysnqn);
522 static struct configfs_group_operations nvmet_namespaces_group_ops = {
523 .make_group = nvmet_ns_make,
526 static const struct config_item_type nvmet_namespaces_type = {
527 .ct_group_ops = &nvmet_namespaces_group_ops,
528 .ct_owner = THIS_MODULE,
531 static int nvmet_port_subsys_allow_link(struct config_item *parent,
532 struct config_item *target)
534 struct nvmet_port *port = to_nvmet_port(parent->ci_parent);
535 struct nvmet_subsys *subsys;
536 struct nvmet_subsys_link *link, *p;
539 if (target->ci_type != &nvmet_subsys_type) {
540 pr_err("can only link subsystems into the subsystems dir.!\n");
543 subsys = to_subsys(target);
544 link = kmalloc(sizeof(*link), GFP_KERNEL);
547 link->subsys = subsys;
549 down_write(&nvmet_config_sem);
551 list_for_each_entry(p, &port->subsystems, entry) {
552 if (p->subsys == subsys)
556 if (list_empty(&port->subsystems)) {
557 ret = nvmet_enable_port(port);
562 list_add_tail(&link->entry, &port->subsystems);
564 up_write(&nvmet_config_sem);
568 up_write(&nvmet_config_sem);
573 static void nvmet_port_subsys_drop_link(struct config_item *parent,
574 struct config_item *target)
576 struct nvmet_port *port = to_nvmet_port(parent->ci_parent);
577 struct nvmet_subsys *subsys = to_subsys(target);
578 struct nvmet_subsys_link *p;
580 down_write(&nvmet_config_sem);
581 list_for_each_entry(p, &port->subsystems, entry) {
582 if (p->subsys == subsys)
585 up_write(&nvmet_config_sem);
591 if (list_empty(&port->subsystems))
592 nvmet_disable_port(port);
593 up_write(&nvmet_config_sem);
597 static struct configfs_item_operations nvmet_port_subsys_item_ops = {
598 .allow_link = nvmet_port_subsys_allow_link,
599 .drop_link = nvmet_port_subsys_drop_link,
602 static const struct config_item_type nvmet_port_subsys_type = {
603 .ct_item_ops = &nvmet_port_subsys_item_ops,
604 .ct_owner = THIS_MODULE,
607 static int nvmet_allowed_hosts_allow_link(struct config_item *parent,
608 struct config_item *target)
610 struct nvmet_subsys *subsys = to_subsys(parent->ci_parent);
611 struct nvmet_host *host;
612 struct nvmet_host_link *link, *p;
615 if (target->ci_type != &nvmet_host_type) {
616 pr_err("can only link hosts into the allowed_hosts directory!\n");
620 host = to_host(target);
621 link = kmalloc(sizeof(*link), GFP_KERNEL);
626 down_write(&nvmet_config_sem);
628 if (subsys->allow_any_host) {
629 pr_err("can't add hosts when allow_any_host is set!\n");
634 list_for_each_entry(p, &subsys->hosts, entry) {
635 if (!strcmp(nvmet_host_name(p->host), nvmet_host_name(host)))
638 list_add_tail(&link->entry, &subsys->hosts);
640 up_write(&nvmet_config_sem);
643 up_write(&nvmet_config_sem);
648 static void nvmet_allowed_hosts_drop_link(struct config_item *parent,
649 struct config_item *target)
651 struct nvmet_subsys *subsys = to_subsys(parent->ci_parent);
652 struct nvmet_host *host = to_host(target);
653 struct nvmet_host_link *p;
655 down_write(&nvmet_config_sem);
656 list_for_each_entry(p, &subsys->hosts, entry) {
657 if (!strcmp(nvmet_host_name(p->host), nvmet_host_name(host)))
660 up_write(&nvmet_config_sem);
666 up_write(&nvmet_config_sem);
670 static struct configfs_item_operations nvmet_allowed_hosts_item_ops = {
671 .allow_link = nvmet_allowed_hosts_allow_link,
672 .drop_link = nvmet_allowed_hosts_drop_link,
675 static const struct config_item_type nvmet_allowed_hosts_type = {
676 .ct_item_ops = &nvmet_allowed_hosts_item_ops,
677 .ct_owner = THIS_MODULE,
680 static ssize_t nvmet_subsys_attr_allow_any_host_show(struct config_item *item,
683 return snprintf(page, PAGE_SIZE, "%d\n",
684 to_subsys(item)->allow_any_host);
687 static ssize_t nvmet_subsys_attr_allow_any_host_store(struct config_item *item,
688 const char *page, size_t count)
690 struct nvmet_subsys *subsys = to_subsys(item);
694 if (strtobool(page, &allow_any_host))
697 down_write(&nvmet_config_sem);
698 if (allow_any_host && !list_empty(&subsys->hosts)) {
699 pr_err("Can't set allow_any_host when explicit hosts are set!\n");
704 subsys->allow_any_host = allow_any_host;
706 up_write(&nvmet_config_sem);
707 return ret ? ret : count;
710 CONFIGFS_ATTR(nvmet_subsys_, attr_allow_any_host);
712 static ssize_t nvmet_subsys_attr_version_show(struct config_item *item,
715 struct nvmet_subsys *subsys = to_subsys(item);
717 if (NVME_TERTIARY(subsys->ver))
718 return snprintf(page, PAGE_SIZE, "%d.%d.%d\n",
719 (int)NVME_MAJOR(subsys->ver),
720 (int)NVME_MINOR(subsys->ver),
721 (int)NVME_TERTIARY(subsys->ver));
723 return snprintf(page, PAGE_SIZE, "%d.%d\n",
724 (int)NVME_MAJOR(subsys->ver),
725 (int)NVME_MINOR(subsys->ver));
728 static ssize_t nvmet_subsys_attr_version_store(struct config_item *item,
729 const char *page, size_t count)
731 struct nvmet_subsys *subsys = to_subsys(item);
732 int major, minor, tertiary = 0;
736 ret = sscanf(page, "%d.%d.%d\n", &major, &minor, &tertiary);
737 if (ret != 2 && ret != 3)
740 down_write(&nvmet_config_sem);
741 subsys->ver = NVME_VS(major, minor, tertiary);
742 up_write(&nvmet_config_sem);
746 CONFIGFS_ATTR(nvmet_subsys_, attr_version);
748 static ssize_t nvmet_subsys_attr_serial_show(struct config_item *item,
751 struct nvmet_subsys *subsys = to_subsys(item);
753 return snprintf(page, PAGE_SIZE, "%llx\n", subsys->serial);
756 static ssize_t nvmet_subsys_attr_serial_store(struct config_item *item,
757 const char *page, size_t count)
759 struct nvmet_subsys *subsys = to_subsys(item);
761 down_write(&nvmet_config_sem);
762 sscanf(page, "%llx\n", &subsys->serial);
763 up_write(&nvmet_config_sem);
767 CONFIGFS_ATTR(nvmet_subsys_, attr_serial);
769 static struct configfs_attribute *nvmet_subsys_attrs[] = {
770 &nvmet_subsys_attr_attr_allow_any_host,
771 &nvmet_subsys_attr_attr_version,
772 &nvmet_subsys_attr_attr_serial,
777 * Subsystem structures & folder operation functions below
779 static void nvmet_subsys_release(struct config_item *item)
781 struct nvmet_subsys *subsys = to_subsys(item);
783 nvmet_subsys_del_ctrls(subsys);
784 nvmet_subsys_put(subsys);
787 static struct configfs_item_operations nvmet_subsys_item_ops = {
788 .release = nvmet_subsys_release,
791 static const struct config_item_type nvmet_subsys_type = {
792 .ct_item_ops = &nvmet_subsys_item_ops,
793 .ct_attrs = nvmet_subsys_attrs,
794 .ct_owner = THIS_MODULE,
797 static struct config_group *nvmet_subsys_make(struct config_group *group,
800 struct nvmet_subsys *subsys;
802 if (sysfs_streq(name, NVME_DISC_SUBSYS_NAME)) {
803 pr_err("can't create discovery subsystem through configfs\n");
804 return ERR_PTR(-EINVAL);
807 subsys = nvmet_subsys_alloc(name, NVME_NQN_NVME);
809 return ERR_PTR(-ENOMEM);
811 config_group_init_type_name(&subsys->group, name, &nvmet_subsys_type);
813 config_group_init_type_name(&subsys->namespaces_group,
814 "namespaces", &nvmet_namespaces_type);
815 configfs_add_default_group(&subsys->namespaces_group, &subsys->group);
817 config_group_init_type_name(&subsys->allowed_hosts_group,
818 "allowed_hosts", &nvmet_allowed_hosts_type);
819 configfs_add_default_group(&subsys->allowed_hosts_group,
822 return &subsys->group;
825 static struct configfs_group_operations nvmet_subsystems_group_ops = {
826 .make_group = nvmet_subsys_make,
829 static const struct config_item_type nvmet_subsystems_type = {
830 .ct_group_ops = &nvmet_subsystems_group_ops,
831 .ct_owner = THIS_MODULE,
834 static ssize_t nvmet_referral_enable_show(struct config_item *item,
837 return snprintf(page, PAGE_SIZE, "%d\n", to_nvmet_port(item)->enabled);
840 static ssize_t nvmet_referral_enable_store(struct config_item *item,
841 const char *page, size_t count)
843 struct nvmet_port *parent = to_nvmet_port(item->ci_parent->ci_parent);
844 struct nvmet_port *port = to_nvmet_port(item);
847 if (strtobool(page, &enable))
851 nvmet_referral_enable(parent, port);
853 nvmet_referral_disable(port);
857 pr_err("Invalid value '%s' for enable\n", page);
861 CONFIGFS_ATTR(nvmet_referral_, enable);
864 * Discovery Service subsystem definitions
866 static struct configfs_attribute *nvmet_referral_attrs[] = {
867 &nvmet_attr_addr_adrfam,
868 &nvmet_attr_addr_portid,
869 &nvmet_attr_addr_treq,
870 &nvmet_attr_addr_traddr,
871 &nvmet_attr_addr_trsvcid,
872 &nvmet_attr_addr_trtype,
873 &nvmet_referral_attr_enable,
877 static void nvmet_referral_release(struct config_item *item)
879 struct nvmet_port *port = to_nvmet_port(item);
881 nvmet_referral_disable(port);
885 static struct configfs_item_operations nvmet_referral_item_ops = {
886 .release = nvmet_referral_release,
889 static const struct config_item_type nvmet_referral_type = {
890 .ct_owner = THIS_MODULE,
891 .ct_attrs = nvmet_referral_attrs,
892 .ct_item_ops = &nvmet_referral_item_ops,
895 static struct config_group *nvmet_referral_make(
896 struct config_group *group, const char *name)
898 struct nvmet_port *port;
900 port = kzalloc(sizeof(*port), GFP_KERNEL);
902 return ERR_PTR(-ENOMEM);
904 INIT_LIST_HEAD(&port->entry);
905 config_group_init_type_name(&port->group, name, &nvmet_referral_type);
910 static struct configfs_group_operations nvmet_referral_group_ops = {
911 .make_group = nvmet_referral_make,
914 static const struct config_item_type nvmet_referrals_type = {
915 .ct_owner = THIS_MODULE,
916 .ct_group_ops = &nvmet_referral_group_ops,
922 static void nvmet_port_release(struct config_item *item)
924 struct nvmet_port *port = to_nvmet_port(item);
929 static struct configfs_attribute *nvmet_port_attrs[] = {
930 &nvmet_attr_addr_adrfam,
931 &nvmet_attr_addr_treq,
932 &nvmet_attr_addr_traddr,
933 &nvmet_attr_addr_trsvcid,
934 &nvmet_attr_addr_trtype,
935 &nvmet_attr_param_inline_data_size,
939 static struct configfs_item_operations nvmet_port_item_ops = {
940 .release = nvmet_port_release,
943 static const struct config_item_type nvmet_port_type = {
944 .ct_attrs = nvmet_port_attrs,
945 .ct_item_ops = &nvmet_port_item_ops,
946 .ct_owner = THIS_MODULE,
949 static struct config_group *nvmet_ports_make(struct config_group *group,
952 struct nvmet_port *port;
955 if (kstrtou16(name, 0, &portid))
956 return ERR_PTR(-EINVAL);
958 port = kzalloc(sizeof(*port), GFP_KERNEL);
960 return ERR_PTR(-ENOMEM);
962 INIT_LIST_HEAD(&port->entry);
963 INIT_LIST_HEAD(&port->subsystems);
964 INIT_LIST_HEAD(&port->referrals);
965 port->inline_data_size = -1; /* < 0 == let the transport choose */
967 port->disc_addr.portid = cpu_to_le16(portid);
968 config_group_init_type_name(&port->group, name, &nvmet_port_type);
970 config_group_init_type_name(&port->subsys_group,
971 "subsystems", &nvmet_port_subsys_type);
972 configfs_add_default_group(&port->subsys_group, &port->group);
974 config_group_init_type_name(&port->referrals_group,
975 "referrals", &nvmet_referrals_type);
976 configfs_add_default_group(&port->referrals_group, &port->group);
981 static struct configfs_group_operations nvmet_ports_group_ops = {
982 .make_group = nvmet_ports_make,
985 static const struct config_item_type nvmet_ports_type = {
986 .ct_group_ops = &nvmet_ports_group_ops,
987 .ct_owner = THIS_MODULE,
990 static struct config_group nvmet_subsystems_group;
991 static struct config_group nvmet_ports_group;
993 static void nvmet_host_release(struct config_item *item)
995 struct nvmet_host *host = to_host(item);
1000 static struct configfs_item_operations nvmet_host_item_ops = {
1001 .release = nvmet_host_release,
1004 static const struct config_item_type nvmet_host_type = {
1005 .ct_item_ops = &nvmet_host_item_ops,
1006 .ct_owner = THIS_MODULE,
1009 static struct config_group *nvmet_hosts_make_group(struct config_group *group,
1012 struct nvmet_host *host;
1014 host = kzalloc(sizeof(*host), GFP_KERNEL);
1016 return ERR_PTR(-ENOMEM);
1018 config_group_init_type_name(&host->group, name, &nvmet_host_type);
1020 return &host->group;
1023 static struct configfs_group_operations nvmet_hosts_group_ops = {
1024 .make_group = nvmet_hosts_make_group,
1027 static const struct config_item_type nvmet_hosts_type = {
1028 .ct_group_ops = &nvmet_hosts_group_ops,
1029 .ct_owner = THIS_MODULE,
1032 static struct config_group nvmet_hosts_group;
1034 static const struct config_item_type nvmet_root_type = {
1035 .ct_owner = THIS_MODULE,
1038 static struct configfs_subsystem nvmet_configfs_subsystem = {
1041 .ci_namebuf = "nvmet",
1042 .ci_type = &nvmet_root_type,
1047 int __init nvmet_init_configfs(void)
1051 config_group_init(&nvmet_configfs_subsystem.su_group);
1052 mutex_init(&nvmet_configfs_subsystem.su_mutex);
1054 config_group_init_type_name(&nvmet_subsystems_group,
1055 "subsystems", &nvmet_subsystems_type);
1056 configfs_add_default_group(&nvmet_subsystems_group,
1057 &nvmet_configfs_subsystem.su_group);
1059 config_group_init_type_name(&nvmet_ports_group,
1060 "ports", &nvmet_ports_type);
1061 configfs_add_default_group(&nvmet_ports_group,
1062 &nvmet_configfs_subsystem.su_group);
1064 config_group_init_type_name(&nvmet_hosts_group,
1065 "hosts", &nvmet_hosts_type);
1066 configfs_add_default_group(&nvmet_hosts_group,
1067 &nvmet_configfs_subsystem.su_group);
1069 ret = configfs_register_subsystem(&nvmet_configfs_subsystem);
1071 pr_err("configfs_register_subsystem: %d\n", ret);
1078 void __exit nvmet_exit_configfs(void)
1080 configfs_unregister_subsystem(&nvmet_configfs_subsystem);