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 struct config_item_type nvmet_host_type;
24 static struct config_item_type nvmet_subsys_type;
27 * nvmet_port Generic ConfigFS definitions.
28 * Used in any place in the ConfigFS tree that refers to an address.
30 static ssize_t nvmet_addr_adrfam_show(struct config_item *item,
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");
43 return sprintf(page, "\n");
47 static ssize_t nvmet_addr_adrfam_store(struct config_item *item,
48 const char *page, size_t count)
50 struct nvmet_port *port = to_nvmet_port(item);
53 pr_err("Cannot modify address while enabled\n");
54 pr_err("Disable the address before modifying\n");
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;
67 pr_err("Invalid value '%s' for adrfam\n", page);
74 CONFIGFS_ATTR(nvmet_, addr_adrfam);
76 static ssize_t nvmet_addr_portid_show(struct config_item *item,
79 struct nvmet_port *port = to_nvmet_port(item);
81 return snprintf(page, PAGE_SIZE, "%d\n",
82 le16_to_cpu(port->disc_addr.portid));
85 static ssize_t nvmet_addr_portid_store(struct config_item *item,
86 const char *page, size_t count)
88 struct nvmet_port *port = to_nvmet_port(item);
91 if (kstrtou16(page, 0, &portid)) {
92 pr_err("Invalid value '%s' for portid\n", page);
97 pr_err("Cannot modify address while enabled\n");
98 pr_err("Disable the address before modifying\n");
101 port->disc_addr.portid = cpu_to_le16(portid);
105 CONFIGFS_ATTR(nvmet_, addr_portid);
107 static ssize_t nvmet_addr_traddr_show(struct config_item *item,
110 struct nvmet_port *port = to_nvmet_port(item);
112 return snprintf(page, PAGE_SIZE, "%s\n",
113 port->disc_addr.traddr);
116 static ssize_t nvmet_addr_traddr_store(struct config_item *item,
117 const char *page, size_t count)
119 struct nvmet_port *port = to_nvmet_port(item);
121 if (count > NVMF_TRADDR_SIZE) {
122 pr_err("Invalid value '%s' for traddr\n", page);
127 pr_err("Cannot modify address while enabled\n");
128 pr_err("Disable the address before modifying\n");
131 return snprintf(port->disc_addr.traddr,
132 sizeof(port->disc_addr.traddr), "%s", page);
135 CONFIGFS_ATTR(nvmet_, addr_traddr);
137 static ssize_t nvmet_addr_treq_show(struct config_item *item,
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");
148 return sprintf(page, "\n");
152 static ssize_t nvmet_addr_treq_store(struct config_item *item,
153 const char *page, size_t count)
155 struct nvmet_port *port = to_nvmet_port(item);
158 pr_err("Cannot modify address while enabled\n");
159 pr_err("Disable the address before modifying\n");
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;
170 pr_err("Invalid value '%s' for treq\n", page);
177 CONFIGFS_ATTR(nvmet_, addr_treq);
179 static ssize_t nvmet_addr_trsvcid_show(struct config_item *item,
182 struct nvmet_port *port = to_nvmet_port(item);
184 return snprintf(page, PAGE_SIZE, "%s\n",
185 port->disc_addr.trsvcid);
188 static ssize_t nvmet_addr_trsvcid_store(struct config_item *item,
189 const char *page, size_t count)
191 struct nvmet_port *port = to_nvmet_port(item);
193 if (count > NVMF_TRSVCID_SIZE) {
194 pr_err("Invalid value '%s' for trsvcid\n", page);
198 pr_err("Cannot modify address while enabled\n");
199 pr_err("Disable the address before modifying\n");
202 return snprintf(port->disc_addr.trsvcid,
203 sizeof(port->disc_addr.trsvcid), "%s", page);
206 CONFIGFS_ATTR(nvmet_, addr_trsvcid);
208 static ssize_t nvmet_addr_trtype_show(struct config_item *item,
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");
217 return sprintf(page, "fc\n");
219 return sprintf(page, "\n");
223 static void nvmet_port_init_tsas_rdma(struct nvmet_port *port)
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;
232 static void nvmet_port_init_tsas_loop(struct nvmet_port *port)
234 port->disc_addr.trtype = NVMF_TRTYPE_LOOP;
235 memset(&port->disc_addr.tsas, 0, NVMF_TSAS_SIZE);
238 static void nvmet_port_init_tsas_fc(struct nvmet_port *port)
240 port->disc_addr.trtype = NVMF_TRTYPE_FC;
241 memset(&port->disc_addr.tsas, 0, NVMF_TSAS_SIZE);
244 static ssize_t nvmet_addr_trtype_store(struct config_item *item,
245 const char *page, size_t count)
247 struct nvmet_port *port = to_nvmet_port(item);
250 pr_err("Cannot modify address while enabled\n");
251 pr_err("Disable the address before modifying\n");
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);
262 pr_err("Invalid value '%s' for trtype\n", page);
269 CONFIGFS_ATTR(nvmet_, addr_trtype);
272 * Namespace structures & file operation functions below
274 static ssize_t nvmet_ns_device_path_show(struct config_item *item, char *page)
276 return sprintf(page, "%s\n", to_nvmet_ns(item)->device_path);
279 static ssize_t nvmet_ns_device_path_store(struct config_item *item,
280 const char *page, size_t count)
282 struct nvmet_ns *ns = to_nvmet_ns(item);
283 struct nvmet_subsys *subsys = ns->subsys;
286 mutex_lock(&subsys->lock);
291 kfree(ns->device_path);
294 ns->device_path = kstrdup(page, GFP_KERNEL);
295 if (!ns->device_path)
298 mutex_unlock(&subsys->lock);
302 mutex_unlock(&subsys->lock);
306 CONFIGFS_ATTR(nvmet_ns_, device_path);
308 static ssize_t nvmet_ns_device_uuid_show(struct config_item *item, char *page)
310 return sprintf(page, "%pUb\n", &to_nvmet_ns(item)->uuid);
313 static ssize_t nvmet_ns_device_uuid_store(struct config_item *item,
314 const char *page, size_t count)
316 struct nvmet_ns *ns = to_nvmet_ns(item);
317 struct nvmet_subsys *subsys = ns->subsys;
321 mutex_lock(&subsys->lock);
328 if (uuid_parse(page, &ns->uuid))
332 mutex_unlock(&subsys->lock);
333 return ret ? ret : count;
336 static ssize_t nvmet_ns_device_nguid_show(struct config_item *item, char *page)
338 return sprintf(page, "%pUb\n", &to_nvmet_ns(item)->nguid);
341 CONFIGFS_ATTR(nvmet_ns_, device_uuid);
343 static ssize_t nvmet_ns_device_nguid_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;
349 const char *p = page;
353 mutex_lock(&subsys->lock);
359 for (i = 0; i < 16; i++) {
360 if (p + 2 > page + count) {
364 if (!isxdigit(p[0]) || !isxdigit(p[1])) {
369 nguid[i] = (hex_to_bin(p[0]) << 4) | hex_to_bin(p[1]);
372 if (*p == '-' || *p == ':')
376 memcpy(&ns->nguid, nguid, sizeof(nguid));
378 mutex_unlock(&subsys->lock);
379 return ret ? ret : count;
382 CONFIGFS_ATTR(nvmet_ns_, device_nguid);
384 static ssize_t nvmet_ns_enable_show(struct config_item *item, char *page)
386 return sprintf(page, "%d\n", to_nvmet_ns(item)->enabled);
389 static ssize_t nvmet_ns_enable_store(struct config_item *item,
390 const char *page, size_t count)
392 struct nvmet_ns *ns = to_nvmet_ns(item);
396 if (strtobool(page, &enable))
400 ret = nvmet_ns_enable(ns);
402 nvmet_ns_disable(ns);
404 return ret ? ret : count;
407 CONFIGFS_ATTR(nvmet_ns_, enable);
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,
417 static void nvmet_ns_release(struct config_item *item)
419 struct nvmet_ns *ns = to_nvmet_ns(item);
424 static struct configfs_item_operations nvmet_ns_item_ops = {
425 .release = nvmet_ns_release,
428 static 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,
434 static struct config_group *nvmet_ns_make(struct config_group *group,
437 struct nvmet_subsys *subsys = namespaces_to_subsys(&group->cg_item);
442 ret = kstrtou32(name, 0, &nsid);
447 if (nsid == 0 || nsid == 0xffffffff)
451 ns = nvmet_ns_alloc(subsys, nsid);
454 config_group_init_type_name(&ns->group, name, &nvmet_ns_type);
456 pr_info("adding nsid %d to subsystem %s\n", nsid, subsys->subsysnqn);
463 static struct configfs_group_operations nvmet_namespaces_group_ops = {
464 .make_group = nvmet_ns_make,
467 static struct config_item_type nvmet_namespaces_type = {
468 .ct_group_ops = &nvmet_namespaces_group_ops,
469 .ct_owner = THIS_MODULE,
472 static int nvmet_port_subsys_allow_link(struct config_item *parent,
473 struct config_item *target)
475 struct nvmet_port *port = to_nvmet_port(parent->ci_parent);
476 struct nvmet_subsys *subsys;
477 struct nvmet_subsys_link *link, *p;
480 if (target->ci_type != &nvmet_subsys_type) {
481 pr_err("can only link subsystems into the subsystems dir.!\n");
484 subsys = to_subsys(target);
485 link = kmalloc(sizeof(*link), GFP_KERNEL);
488 link->subsys = subsys;
490 down_write(&nvmet_config_sem);
492 list_for_each_entry(p, &port->subsystems, entry) {
493 if (p->subsys == subsys)
497 if (list_empty(&port->subsystems)) {
498 ret = nvmet_enable_port(port);
503 list_add_tail(&link->entry, &port->subsystems);
505 up_write(&nvmet_config_sem);
509 up_write(&nvmet_config_sem);
514 static void nvmet_port_subsys_drop_link(struct config_item *parent,
515 struct config_item *target)
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;
521 down_write(&nvmet_config_sem);
522 list_for_each_entry(p, &port->subsystems, entry) {
523 if (p->subsys == subsys)
526 up_write(&nvmet_config_sem);
532 if (list_empty(&port->subsystems))
533 nvmet_disable_port(port);
534 up_write(&nvmet_config_sem);
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,
543 static struct config_item_type nvmet_port_subsys_type = {
544 .ct_item_ops = &nvmet_port_subsys_item_ops,
545 .ct_owner = THIS_MODULE,
548 static int nvmet_allowed_hosts_allow_link(struct config_item *parent,
549 struct config_item *target)
551 struct nvmet_subsys *subsys = to_subsys(parent->ci_parent);
552 struct nvmet_host *host;
553 struct nvmet_host_link *link, *p;
556 if (target->ci_type != &nvmet_host_type) {
557 pr_err("can only link hosts into the allowed_hosts directory!\n");
561 host = to_host(target);
562 link = kmalloc(sizeof(*link), GFP_KERNEL);
567 down_write(&nvmet_config_sem);
569 if (subsys->allow_any_host) {
570 pr_err("can't add hosts when allow_any_host is set!\n");
575 list_for_each_entry(p, &subsys->hosts, entry) {
576 if (!strcmp(nvmet_host_name(p->host), nvmet_host_name(host)))
579 list_add_tail(&link->entry, &subsys->hosts);
581 up_write(&nvmet_config_sem);
584 up_write(&nvmet_config_sem);
589 static void nvmet_allowed_hosts_drop_link(struct config_item *parent,
590 struct config_item *target)
592 struct nvmet_subsys *subsys = to_subsys(parent->ci_parent);
593 struct nvmet_host *host = to_host(target);
594 struct nvmet_host_link *p;
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)))
601 up_write(&nvmet_config_sem);
607 up_write(&nvmet_config_sem);
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,
616 static struct config_item_type nvmet_allowed_hosts_type = {
617 .ct_item_ops = &nvmet_allowed_hosts_item_ops,
618 .ct_owner = THIS_MODULE,
621 static ssize_t nvmet_subsys_attr_allow_any_host_show(struct config_item *item,
624 return snprintf(page, PAGE_SIZE, "%d\n",
625 to_subsys(item)->allow_any_host);
628 static ssize_t nvmet_subsys_attr_allow_any_host_store(struct config_item *item,
629 const char *page, size_t count)
631 struct nvmet_subsys *subsys = to_subsys(item);
635 if (strtobool(page, &allow_any_host))
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");
645 subsys->allow_any_host = allow_any_host;
647 up_write(&nvmet_config_sem);
648 return ret ? ret : count;
651 CONFIGFS_ATTR(nvmet_subsys_, attr_allow_any_host);
653 static ssize_t nvmet_subsys_version_show(struct config_item *item,
656 struct nvmet_subsys *subsys = to_subsys(item);
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));
664 return snprintf(page, PAGE_SIZE, "%d.%d\n",
665 (int)NVME_MAJOR(subsys->ver),
666 (int)NVME_MINOR(subsys->ver));
669 static ssize_t nvmet_subsys_version_store(struct config_item *item,
670 const char *page, size_t count)
672 struct nvmet_subsys *subsys = to_subsys(item);
673 int major, minor, tertiary = 0;
677 ret = sscanf(page, "%d.%d.%d\n", &major, &minor, &tertiary);
678 if (ret != 2 && ret != 3)
681 down_write(&nvmet_config_sem);
682 subsys->ver = NVME_VS(major, minor, tertiary);
683 up_write(&nvmet_config_sem);
687 CONFIGFS_ATTR(nvmet_subsys_, version);
689 static struct configfs_attribute *nvmet_subsys_attrs[] = {
690 &nvmet_subsys_attr_attr_allow_any_host,
691 &nvmet_subsys_attr_version,
696 * Subsystem structures & folder operation functions below
698 static void nvmet_subsys_release(struct config_item *item)
700 struct nvmet_subsys *subsys = to_subsys(item);
702 nvmet_subsys_del_ctrls(subsys);
703 nvmet_subsys_put(subsys);
706 static struct configfs_item_operations nvmet_subsys_item_ops = {
707 .release = nvmet_subsys_release,
710 static struct config_item_type nvmet_subsys_type = {
711 .ct_item_ops = &nvmet_subsys_item_ops,
712 .ct_attrs = nvmet_subsys_attrs,
713 .ct_owner = THIS_MODULE,
716 static struct config_group *nvmet_subsys_make(struct config_group *group,
719 struct nvmet_subsys *subsys;
721 if (sysfs_streq(name, NVME_DISC_SUBSYS_NAME)) {
722 pr_err("can't create discovery subsystem through configfs\n");
723 return ERR_PTR(-EINVAL);
726 subsys = nvmet_subsys_alloc(name, NVME_NQN_NVME);
728 return ERR_PTR(-ENOMEM);
730 config_group_init_type_name(&subsys->group, name, &nvmet_subsys_type);
732 config_group_init_type_name(&subsys->namespaces_group,
733 "namespaces", &nvmet_namespaces_type);
734 configfs_add_default_group(&subsys->namespaces_group, &subsys->group);
736 config_group_init_type_name(&subsys->allowed_hosts_group,
737 "allowed_hosts", &nvmet_allowed_hosts_type);
738 configfs_add_default_group(&subsys->allowed_hosts_group,
741 return &subsys->group;
744 static struct configfs_group_operations nvmet_subsystems_group_ops = {
745 .make_group = nvmet_subsys_make,
748 static struct config_item_type nvmet_subsystems_type = {
749 .ct_group_ops = &nvmet_subsystems_group_ops,
750 .ct_owner = THIS_MODULE,
753 static ssize_t nvmet_referral_enable_show(struct config_item *item,
756 return snprintf(page, PAGE_SIZE, "%d\n", to_nvmet_port(item)->enabled);
759 static ssize_t nvmet_referral_enable_store(struct config_item *item,
760 const char *page, size_t count)
762 struct nvmet_port *parent = to_nvmet_port(item->ci_parent->ci_parent);
763 struct nvmet_port *port = to_nvmet_port(item);
766 if (strtobool(page, &enable))
770 nvmet_referral_enable(parent, port);
772 nvmet_referral_disable(port);
776 pr_err("Invalid value '%s' for enable\n", page);
780 CONFIGFS_ATTR(nvmet_referral_, enable);
783 * Discovery Service subsystem definitions
785 static struct configfs_attribute *nvmet_referral_attrs[] = {
786 &nvmet_attr_addr_adrfam,
787 &nvmet_attr_addr_portid,
788 &nvmet_attr_addr_treq,
789 &nvmet_attr_addr_traddr,
790 &nvmet_attr_addr_trsvcid,
791 &nvmet_attr_addr_trtype,
792 &nvmet_referral_attr_enable,
796 static void nvmet_referral_release(struct config_item *item)
798 struct nvmet_port *port = to_nvmet_port(item);
800 nvmet_referral_disable(port);
804 static struct configfs_item_operations nvmet_referral_item_ops = {
805 .release = nvmet_referral_release,
808 static struct config_item_type nvmet_referral_type = {
809 .ct_owner = THIS_MODULE,
810 .ct_attrs = nvmet_referral_attrs,
811 .ct_item_ops = &nvmet_referral_item_ops,
814 static struct config_group *nvmet_referral_make(
815 struct config_group *group, const char *name)
817 struct nvmet_port *port;
819 port = kzalloc(sizeof(*port), GFP_KERNEL);
821 return ERR_PTR(-ENOMEM);
823 INIT_LIST_HEAD(&port->entry);
824 config_group_init_type_name(&port->group, name, &nvmet_referral_type);
829 static struct configfs_group_operations nvmet_referral_group_ops = {
830 .make_group = nvmet_referral_make,
833 static struct config_item_type nvmet_referrals_type = {
834 .ct_owner = THIS_MODULE,
835 .ct_group_ops = &nvmet_referral_group_ops,
841 static void nvmet_port_release(struct config_item *item)
843 struct nvmet_port *port = to_nvmet_port(item);
848 static struct configfs_attribute *nvmet_port_attrs[] = {
849 &nvmet_attr_addr_adrfam,
850 &nvmet_attr_addr_treq,
851 &nvmet_attr_addr_traddr,
852 &nvmet_attr_addr_trsvcid,
853 &nvmet_attr_addr_trtype,
857 static struct configfs_item_operations nvmet_port_item_ops = {
858 .release = nvmet_port_release,
861 static struct config_item_type nvmet_port_type = {
862 .ct_attrs = nvmet_port_attrs,
863 .ct_item_ops = &nvmet_port_item_ops,
864 .ct_owner = THIS_MODULE,
867 static struct config_group *nvmet_ports_make(struct config_group *group,
870 struct nvmet_port *port;
873 if (kstrtou16(name, 0, &portid))
874 return ERR_PTR(-EINVAL);
876 port = kzalloc(sizeof(*port), GFP_KERNEL);
878 return ERR_PTR(-ENOMEM);
880 INIT_LIST_HEAD(&port->entry);
881 INIT_LIST_HEAD(&port->subsystems);
882 INIT_LIST_HEAD(&port->referrals);
884 port->disc_addr.portid = cpu_to_le16(portid);
885 config_group_init_type_name(&port->group, name, &nvmet_port_type);
887 config_group_init_type_name(&port->subsys_group,
888 "subsystems", &nvmet_port_subsys_type);
889 configfs_add_default_group(&port->subsys_group, &port->group);
891 config_group_init_type_name(&port->referrals_group,
892 "referrals", &nvmet_referrals_type);
893 configfs_add_default_group(&port->referrals_group, &port->group);
898 static struct configfs_group_operations nvmet_ports_group_ops = {
899 .make_group = nvmet_ports_make,
902 static struct config_item_type nvmet_ports_type = {
903 .ct_group_ops = &nvmet_ports_group_ops,
904 .ct_owner = THIS_MODULE,
907 static struct config_group nvmet_subsystems_group;
908 static struct config_group nvmet_ports_group;
910 static void nvmet_host_release(struct config_item *item)
912 struct nvmet_host *host = to_host(item);
917 static struct configfs_item_operations nvmet_host_item_ops = {
918 .release = nvmet_host_release,
921 static struct config_item_type nvmet_host_type = {
922 .ct_item_ops = &nvmet_host_item_ops,
923 .ct_owner = THIS_MODULE,
926 static struct config_group *nvmet_hosts_make_group(struct config_group *group,
929 struct nvmet_host *host;
931 host = kzalloc(sizeof(*host), GFP_KERNEL);
933 return ERR_PTR(-ENOMEM);
935 config_group_init_type_name(&host->group, name, &nvmet_host_type);
940 static struct configfs_group_operations nvmet_hosts_group_ops = {
941 .make_group = nvmet_hosts_make_group,
944 static struct config_item_type nvmet_hosts_type = {
945 .ct_group_ops = &nvmet_hosts_group_ops,
946 .ct_owner = THIS_MODULE,
949 static struct config_group nvmet_hosts_group;
951 static struct config_item_type nvmet_root_type = {
952 .ct_owner = THIS_MODULE,
955 static struct configfs_subsystem nvmet_configfs_subsystem = {
958 .ci_namebuf = "nvmet",
959 .ci_type = &nvmet_root_type,
964 int __init nvmet_init_configfs(void)
968 config_group_init(&nvmet_configfs_subsystem.su_group);
969 mutex_init(&nvmet_configfs_subsystem.su_mutex);
971 config_group_init_type_name(&nvmet_subsystems_group,
972 "subsystems", &nvmet_subsystems_type);
973 configfs_add_default_group(&nvmet_subsystems_group,
974 &nvmet_configfs_subsystem.su_group);
976 config_group_init_type_name(&nvmet_ports_group,
977 "ports", &nvmet_ports_type);
978 configfs_add_default_group(&nvmet_ports_group,
979 &nvmet_configfs_subsystem.su_group);
981 config_group_init_type_name(&nvmet_hosts_group,
982 "hosts", &nvmet_hosts_type);
983 configfs_add_default_group(&nvmet_hosts_group,
984 &nvmet_configfs_subsystem.su_group);
986 ret = configfs_register_subsystem(&nvmet_configfs_subsystem);
988 pr_err("configfs_register_subsystem: %d\n", ret);
995 void __exit nvmet_exit_configfs(void)
997 configfs_unregister_subsystem(&nvmet_configfs_subsystem);