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
;
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 const struct config_item_type nvmet_ns_type
= {
429 .ct_item_ops
= &nvmet_ns_item_ops
,
430 .ct_attrs
= nvmet_ns_attrs
,
431 .ct_owner
= THIS_MODULE
,
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
== NVME_NSID_ALL
)
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 const 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 const 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 const 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_attr_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_attr_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_
, attr_version
);
689 static ssize_t
nvmet_subsys_attr_serial_show(struct config_item
*item
,
692 struct nvmet_subsys
*subsys
= to_subsys(item
);
694 return snprintf(page
, PAGE_SIZE
, "%llx\n", subsys
->serial
);
697 static ssize_t
nvmet_subsys_attr_serial_store(struct config_item
*item
,
698 const char *page
, size_t count
)
700 struct nvmet_subsys
*subsys
= to_subsys(item
);
702 down_write(&nvmet_config_sem
);
703 sscanf(page
, "%llx\n", &subsys
->serial
);
704 up_write(&nvmet_config_sem
);
708 CONFIGFS_ATTR(nvmet_subsys_
, attr_serial
);
710 static struct configfs_attribute
*nvmet_subsys_attrs
[] = {
711 &nvmet_subsys_attr_attr_allow_any_host
,
712 &nvmet_subsys_attr_attr_version
,
713 &nvmet_subsys_attr_attr_serial
,
718 * Subsystem structures & folder operation functions below
720 static void nvmet_subsys_release(struct config_item
*item
)
722 struct nvmet_subsys
*subsys
= to_subsys(item
);
724 nvmet_subsys_del_ctrls(subsys
);
725 nvmet_subsys_put(subsys
);
728 static struct configfs_item_operations nvmet_subsys_item_ops
= {
729 .release
= nvmet_subsys_release
,
732 static const struct config_item_type nvmet_subsys_type
= {
733 .ct_item_ops
= &nvmet_subsys_item_ops
,
734 .ct_attrs
= nvmet_subsys_attrs
,
735 .ct_owner
= THIS_MODULE
,
738 static struct config_group
*nvmet_subsys_make(struct config_group
*group
,
741 struct nvmet_subsys
*subsys
;
743 if (sysfs_streq(name
, NVME_DISC_SUBSYS_NAME
)) {
744 pr_err("can't create discovery subsystem through configfs\n");
745 return ERR_PTR(-EINVAL
);
748 subsys
= nvmet_subsys_alloc(name
, NVME_NQN_NVME
);
750 return ERR_PTR(-ENOMEM
);
752 config_group_init_type_name(&subsys
->group
, name
, &nvmet_subsys_type
);
754 config_group_init_type_name(&subsys
->namespaces_group
,
755 "namespaces", &nvmet_namespaces_type
);
756 configfs_add_default_group(&subsys
->namespaces_group
, &subsys
->group
);
758 config_group_init_type_name(&subsys
->allowed_hosts_group
,
759 "allowed_hosts", &nvmet_allowed_hosts_type
);
760 configfs_add_default_group(&subsys
->allowed_hosts_group
,
763 return &subsys
->group
;
766 static struct configfs_group_operations nvmet_subsystems_group_ops
= {
767 .make_group
= nvmet_subsys_make
,
770 static const struct config_item_type nvmet_subsystems_type
= {
771 .ct_group_ops
= &nvmet_subsystems_group_ops
,
772 .ct_owner
= THIS_MODULE
,
775 static ssize_t
nvmet_referral_enable_show(struct config_item
*item
,
778 return snprintf(page
, PAGE_SIZE
, "%d\n", to_nvmet_port(item
)->enabled
);
781 static ssize_t
nvmet_referral_enable_store(struct config_item
*item
,
782 const char *page
, size_t count
)
784 struct nvmet_port
*parent
= to_nvmet_port(item
->ci_parent
->ci_parent
);
785 struct nvmet_port
*port
= to_nvmet_port(item
);
788 if (strtobool(page
, &enable
))
792 nvmet_referral_enable(parent
, port
);
794 nvmet_referral_disable(port
);
798 pr_err("Invalid value '%s' for enable\n", page
);
802 CONFIGFS_ATTR(nvmet_referral_
, enable
);
805 * Discovery Service subsystem definitions
807 static struct configfs_attribute
*nvmet_referral_attrs
[] = {
808 &nvmet_attr_addr_adrfam
,
809 &nvmet_attr_addr_portid
,
810 &nvmet_attr_addr_treq
,
811 &nvmet_attr_addr_traddr
,
812 &nvmet_attr_addr_trsvcid
,
813 &nvmet_attr_addr_trtype
,
814 &nvmet_referral_attr_enable
,
818 static void nvmet_referral_release(struct config_item
*item
)
820 struct nvmet_port
*port
= to_nvmet_port(item
);
822 nvmet_referral_disable(port
);
826 static struct configfs_item_operations nvmet_referral_item_ops
= {
827 .release
= nvmet_referral_release
,
830 static const struct config_item_type nvmet_referral_type
= {
831 .ct_owner
= THIS_MODULE
,
832 .ct_attrs
= nvmet_referral_attrs
,
833 .ct_item_ops
= &nvmet_referral_item_ops
,
836 static struct config_group
*nvmet_referral_make(
837 struct config_group
*group
, const char *name
)
839 struct nvmet_port
*port
;
841 port
= kzalloc(sizeof(*port
), GFP_KERNEL
);
843 return ERR_PTR(-ENOMEM
);
845 INIT_LIST_HEAD(&port
->entry
);
846 config_group_init_type_name(&port
->group
, name
, &nvmet_referral_type
);
851 static struct configfs_group_operations nvmet_referral_group_ops
= {
852 .make_group
= nvmet_referral_make
,
855 static const struct config_item_type nvmet_referrals_type
= {
856 .ct_owner
= THIS_MODULE
,
857 .ct_group_ops
= &nvmet_referral_group_ops
,
863 static void nvmet_port_release(struct config_item
*item
)
865 struct nvmet_port
*port
= to_nvmet_port(item
);
870 static struct configfs_attribute
*nvmet_port_attrs
[] = {
871 &nvmet_attr_addr_adrfam
,
872 &nvmet_attr_addr_treq
,
873 &nvmet_attr_addr_traddr
,
874 &nvmet_attr_addr_trsvcid
,
875 &nvmet_attr_addr_trtype
,
879 static struct configfs_item_operations nvmet_port_item_ops
= {
880 .release
= nvmet_port_release
,
883 static const struct config_item_type nvmet_port_type
= {
884 .ct_attrs
= nvmet_port_attrs
,
885 .ct_item_ops
= &nvmet_port_item_ops
,
886 .ct_owner
= THIS_MODULE
,
889 static struct config_group
*nvmet_ports_make(struct config_group
*group
,
892 struct nvmet_port
*port
;
895 if (kstrtou16(name
, 0, &portid
))
896 return ERR_PTR(-EINVAL
);
898 port
= kzalloc(sizeof(*port
), GFP_KERNEL
);
900 return ERR_PTR(-ENOMEM
);
902 INIT_LIST_HEAD(&port
->entry
);
903 INIT_LIST_HEAD(&port
->subsystems
);
904 INIT_LIST_HEAD(&port
->referrals
);
906 port
->disc_addr
.portid
= cpu_to_le16(portid
);
907 config_group_init_type_name(&port
->group
, name
, &nvmet_port_type
);
909 config_group_init_type_name(&port
->subsys_group
,
910 "subsystems", &nvmet_port_subsys_type
);
911 configfs_add_default_group(&port
->subsys_group
, &port
->group
);
913 config_group_init_type_name(&port
->referrals_group
,
914 "referrals", &nvmet_referrals_type
);
915 configfs_add_default_group(&port
->referrals_group
, &port
->group
);
920 static struct configfs_group_operations nvmet_ports_group_ops
= {
921 .make_group
= nvmet_ports_make
,
924 static const struct config_item_type nvmet_ports_type
= {
925 .ct_group_ops
= &nvmet_ports_group_ops
,
926 .ct_owner
= THIS_MODULE
,
929 static struct config_group nvmet_subsystems_group
;
930 static struct config_group nvmet_ports_group
;
932 static void nvmet_host_release(struct config_item
*item
)
934 struct nvmet_host
*host
= to_host(item
);
939 static struct configfs_item_operations nvmet_host_item_ops
= {
940 .release
= nvmet_host_release
,
943 static const struct config_item_type nvmet_host_type
= {
944 .ct_item_ops
= &nvmet_host_item_ops
,
945 .ct_owner
= THIS_MODULE
,
948 static struct config_group
*nvmet_hosts_make_group(struct config_group
*group
,
951 struct nvmet_host
*host
;
953 host
= kzalloc(sizeof(*host
), GFP_KERNEL
);
955 return ERR_PTR(-ENOMEM
);
957 config_group_init_type_name(&host
->group
, name
, &nvmet_host_type
);
962 static struct configfs_group_operations nvmet_hosts_group_ops
= {
963 .make_group
= nvmet_hosts_make_group
,
966 static const struct config_item_type nvmet_hosts_type
= {
967 .ct_group_ops
= &nvmet_hosts_group_ops
,
968 .ct_owner
= THIS_MODULE
,
971 static struct config_group nvmet_hosts_group
;
973 static const struct config_item_type nvmet_root_type
= {
974 .ct_owner
= THIS_MODULE
,
977 static struct configfs_subsystem nvmet_configfs_subsystem
= {
980 .ci_namebuf
= "nvmet",
981 .ci_type
= &nvmet_root_type
,
986 int __init
nvmet_init_configfs(void)
990 config_group_init(&nvmet_configfs_subsystem
.su_group
);
991 mutex_init(&nvmet_configfs_subsystem
.su_mutex
);
993 config_group_init_type_name(&nvmet_subsystems_group
,
994 "subsystems", &nvmet_subsystems_type
);
995 configfs_add_default_group(&nvmet_subsystems_group
,
996 &nvmet_configfs_subsystem
.su_group
);
998 config_group_init_type_name(&nvmet_ports_group
,
999 "ports", &nvmet_ports_type
);
1000 configfs_add_default_group(&nvmet_ports_group
,
1001 &nvmet_configfs_subsystem
.su_group
);
1003 config_group_init_type_name(&nvmet_hosts_group
,
1004 "hosts", &nvmet_hosts_type
);
1005 configfs_add_default_group(&nvmet_hosts_group
,
1006 &nvmet_configfs_subsystem
.su_group
);
1008 ret
= configfs_register_subsystem(&nvmet_configfs_subsystem
);
1010 pr_err("configfs_register_subsystem: %d\n", ret
);
1017 void __exit
nvmet_exit_configfs(void)
1019 configfs_unregister_subsystem(&nvmet_configfs_subsystem
);