1
2
3
4
5
6
7
8
9
10
11
12
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
23static struct config_item_type nvmet_host_type;
24static struct config_item_type nvmet_subsys_type;
25
26static const struct nvmet_transport_name {
27 u8 type;
28 const char *name;
29} nvmet_transport_names[] = {
30 { NVMF_TRTYPE_RDMA, "rdma" },
31 { NVMF_TRTYPE_FC, "fc" },
32 { NVMF_TRTYPE_LOOP, "loop" },
33};
34
35
36
37
38
39static ssize_t nvmet_addr_adrfam_show(struct config_item *item,
40 char *page)
41{
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");
51 default:
52 return sprintf(page, "\n");
53 }
54}
55
56static ssize_t nvmet_addr_adrfam_store(struct config_item *item,
57 const char *page, size_t count)
58{
59 struct nvmet_port *port = to_nvmet_port(item);
60
61 if (port->enabled) {
62 pr_err("Cannot modify address while enabled\n");
63 pr_err("Disable the address before modifying\n");
64 return -EACCES;
65 }
66
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;
75 } else {
76 pr_err("Invalid value '%s' for adrfam\n", page);
77 return -EINVAL;
78 }
79
80 return count;
81}
82
83CONFIGFS_ATTR(nvmet_, addr_adrfam);
84
85static ssize_t nvmet_addr_portid_show(struct config_item *item,
86 char *page)
87{
88 struct nvmet_port *port = to_nvmet_port(item);
89
90 return snprintf(page, PAGE_SIZE, "%d\n",
91 le16_to_cpu(port->disc_addr.portid));
92}
93
94static ssize_t nvmet_addr_portid_store(struct config_item *item,
95 const char *page, size_t count)
96{
97 struct nvmet_port *port = to_nvmet_port(item);
98 u16 portid = 0;
99
100 if (kstrtou16(page, 0, &portid)) {
101 pr_err("Invalid value '%s' for portid\n", page);
102 return -EINVAL;
103 }
104
105 if (port->enabled) {
106 pr_err("Cannot modify address while enabled\n");
107 pr_err("Disable the address before modifying\n");
108 return -EACCES;
109 }
110 port->disc_addr.portid = cpu_to_le16(portid);
111 return count;
112}
113
114CONFIGFS_ATTR(nvmet_, addr_portid);
115
116static ssize_t nvmet_addr_traddr_show(struct config_item *item,
117 char *page)
118{
119 struct nvmet_port *port = to_nvmet_port(item);
120
121 return snprintf(page, PAGE_SIZE, "%s\n",
122 port->disc_addr.traddr);
123}
124
125static ssize_t nvmet_addr_traddr_store(struct config_item *item,
126 const char *page, size_t count)
127{
128 struct nvmet_port *port = to_nvmet_port(item);
129
130 if (count > NVMF_TRADDR_SIZE) {
131 pr_err("Invalid value '%s' for traddr\n", page);
132 return -EINVAL;
133 }
134
135 if (port->enabled) {
136 pr_err("Cannot modify address while enabled\n");
137 pr_err("Disable the address before modifying\n");
138 return -EACCES;
139 }
140
141 if (sscanf(page, "%s\n", port->disc_addr.traddr) != 1)
142 return -EINVAL;
143 return count;
144}
145
146CONFIGFS_ATTR(nvmet_, addr_traddr);
147
148static ssize_t nvmet_addr_treq_show(struct config_item *item,
149 char *page)
150{
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");
158 default:
159 return sprintf(page, "\n");
160 }
161}
162
163static ssize_t nvmet_addr_treq_store(struct config_item *item,
164 const char *page, size_t count)
165{
166 struct nvmet_port *port = to_nvmet_port(item);
167
168 if (port->enabled) {
169 pr_err("Cannot modify address while enabled\n");
170 pr_err("Disable the address before modifying\n");
171 return -EACCES;
172 }
173
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;
180 } else {
181 pr_err("Invalid value '%s' for treq\n", page);
182 return -EINVAL;
183 }
184
185 return count;
186}
187
188CONFIGFS_ATTR(nvmet_, addr_treq);
189
190static ssize_t nvmet_addr_trsvcid_show(struct config_item *item,
191 char *page)
192{
193 struct nvmet_port *port = to_nvmet_port(item);
194
195 return snprintf(page, PAGE_SIZE, "%s\n",
196 port->disc_addr.trsvcid);
197}
198
199static ssize_t nvmet_addr_trsvcid_store(struct config_item *item,
200 const char *page, size_t count)
201{
202 struct nvmet_port *port = to_nvmet_port(item);
203
204 if (count > NVMF_TRSVCID_SIZE) {
205 pr_err("Invalid value '%s' for trsvcid\n", page);
206 return -EINVAL;
207 }
208 if (port->enabled) {
209 pr_err("Cannot modify address while enabled\n");
210 pr_err("Disable the address before modifying\n");
211 return -EACCES;
212 }
213
214 if (sscanf(page, "%s\n", port->disc_addr.trsvcid) != 1)
215 return -EINVAL;
216 return count;
217}
218
219CONFIGFS_ATTR(nvmet_, addr_trsvcid);
220
221static ssize_t nvmet_param_inline_data_size_show(struct config_item *item,
222 char *page)
223{
224 struct nvmet_port *port = to_nvmet_port(item);
225
226 return snprintf(page, PAGE_SIZE, "%d\n", port->inline_data_size);
227}
228
229static ssize_t nvmet_param_inline_data_size_store(struct config_item *item,
230 const char *page, size_t count)
231{
232 struct nvmet_port *port = to_nvmet_port(item);
233 int ret;
234
235 if (port->enabled) {
236 pr_err("Cannot modify inline_data_size while port enabled\n");
237 pr_err("Disable the port before modifying\n");
238 return -EACCES;
239 }
240 ret = kstrtoint(page, 0, &port->inline_data_size);
241 if (ret) {
242 pr_err("Invalid value '%s' for inline_data_size\n", page);
243 return -EINVAL;
244 }
245 return count;
246}
247
248CONFIGFS_ATTR(nvmet_, param_inline_data_size);
249
250static ssize_t nvmet_addr_trtype_show(struct config_item *item,
251 char *page)
252{
253 struct nvmet_port *port = to_nvmet_port(item);
254 int i;
255
256 for (i = 0; i < ARRAY_SIZE(nvmet_transport_names); i++) {
257 if (port->disc_addr.trtype != nvmet_transport_names[i].type)
258 continue;
259 return sprintf(page, "%s\n", nvmet_transport_names[i].name);
260 }
261
262 return sprintf(page, "\n");
263}
264
265static void nvmet_port_init_tsas_rdma(struct nvmet_port *port)
266{
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;
270}
271
272static ssize_t nvmet_addr_trtype_store(struct config_item *item,
273 const char *page, size_t count)
274{
275 struct nvmet_port *port = to_nvmet_port(item);
276 int i;
277
278 if (port->enabled) {
279 pr_err("Cannot modify address while enabled\n");
280 pr_err("Disable the address before modifying\n");
281 return -EACCES;
282 }
283
284 for (i = 0; i < ARRAY_SIZE(nvmet_transport_names); i++) {
285 if (sysfs_streq(page, nvmet_transport_names[i].name))
286 goto found;
287 }
288
289 pr_err("Invalid value '%s' for trtype\n", page);
290 return -EINVAL;
291found:
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);
296 return count;
297}
298
299CONFIGFS_ATTR(nvmet_, addr_trtype);
300
301
302
303
304static ssize_t nvmet_ns_device_path_show(struct config_item *item, char *page)
305{
306 return sprintf(page, "%s\n", to_nvmet_ns(item)->device_path);
307}
308
309static ssize_t nvmet_ns_device_path_store(struct config_item *item,
310 const char *page, size_t count)
311{
312 struct nvmet_ns *ns = to_nvmet_ns(item);
313 struct nvmet_subsys *subsys = ns->subsys;
314 size_t len;
315 int ret;
316
317 mutex_lock(&subsys->lock);
318 ret = -EBUSY;
319 if (ns->enabled)
320 goto out_unlock;
321
322 ret = -EINVAL;
323 len = strcspn(page, "\n");
324 if (!len)
325 goto out_unlock;
326
327 kfree(ns->device_path);
328 ret = -ENOMEM;
329 ns->device_path = kstrndup(page, len, GFP_KERNEL);
330 if (!ns->device_path)
331 goto out_unlock;
332
333 mutex_unlock(&subsys->lock);
334 return count;
335
336out_unlock:
337 mutex_unlock(&subsys->lock);
338 return ret;
339}
340
341CONFIGFS_ATTR(nvmet_ns_, device_path);
342
343static ssize_t nvmet_ns_device_uuid_show(struct config_item *item, char *page)
344{
345 return sprintf(page, "%pUb\n", &to_nvmet_ns(item)->uuid);
346}
347
348static ssize_t nvmet_ns_device_uuid_store(struct config_item *item,
349 const char *page, size_t count)
350{
351 struct nvmet_ns *ns = to_nvmet_ns(item);
352 struct nvmet_subsys *subsys = ns->subsys;
353 int ret = 0;
354
355
356 mutex_lock(&subsys->lock);
357 if (ns->enabled) {
358 ret = -EBUSY;
359 goto out_unlock;
360 }
361
362
363 if (uuid_be_to_bin(page, &ns->uuid))
364 ret = -EINVAL;
365
366out_unlock:
367 mutex_unlock(&subsys->lock);
368 return ret ? ret : count;
369}
370
371CONFIGFS_ATTR(nvmet_ns_, device_uuid);
372
373static ssize_t nvmet_ns_device_nguid_show(struct config_item *item, char *page)
374{
375 return sprintf(page, "%pUb\n", &to_nvmet_ns(item)->nguid);
376}
377
378static ssize_t nvmet_ns_device_nguid_store(struct config_item *item,
379 const char *page, size_t count)
380{
381 struct nvmet_ns *ns = to_nvmet_ns(item);
382 struct nvmet_subsys *subsys = ns->subsys;
383 u8 nguid[16];
384 const char *p = page;
385 int i;
386 int ret = 0;
387
388 mutex_lock(&subsys->lock);
389 if (ns->enabled) {
390 ret = -EBUSY;
391 goto out_unlock;
392 }
393
394 for (i = 0; i < 16; i++) {
395 if (p + 2 > page + count) {
396 ret = -EINVAL;
397 goto out_unlock;
398 }
399 if (!isxdigit(p[0]) || !isxdigit(p[1])) {
400 ret = -EINVAL;
401 goto out_unlock;
402 }
403
404 nguid[i] = (hex_to_bin(p[0]) << 4) | hex_to_bin(p[1]);
405 p += 2;
406
407 if (*p == '-' || *p == ':')
408 p++;
409 }
410
411 memcpy(&ns->nguid, nguid, sizeof(nguid));
412out_unlock:
413 mutex_unlock(&subsys->lock);
414 return ret ? ret : count;
415}
416
417CONFIGFS_ATTR(nvmet_ns_, device_nguid);
418
419static ssize_t nvmet_ns_enable_show(struct config_item *item, char *page)
420{
421 return sprintf(page, "%d\n", to_nvmet_ns(item)->enabled);
422}
423
424static ssize_t nvmet_ns_enable_store(struct config_item *item,
425 const char *page, size_t count)
426{
427 struct nvmet_ns *ns = to_nvmet_ns(item);
428 bool enable;
429 int ret = 0;
430
431 if (strtobool(page, &enable))
432 return -EINVAL;
433
434 if (enable)
435 ret = nvmet_ns_enable(ns);
436 else
437 nvmet_ns_disable(ns);
438
439 return ret ? ret : count;
440}
441
442CONFIGFS_ATTR(nvmet_ns_, enable);
443
444static struct configfs_attribute *nvmet_ns_attrs[] = {
445 &nvmet_ns_attr_device_path,
446 &nvmet_ns_attr_device_nguid,
447 &nvmet_ns_attr_device_uuid,
448 &nvmet_ns_attr_enable,
449 NULL,
450};
451
452static void nvmet_ns_release(struct config_item *item)
453{
454 struct nvmet_ns *ns = to_nvmet_ns(item);
455
456 nvmet_ns_free(ns);
457}
458
459static struct configfs_item_operations nvmet_ns_item_ops = {
460 .release = nvmet_ns_release,
461};
462
463static struct config_item_type nvmet_ns_type = {
464 .ct_item_ops = &nvmet_ns_item_ops,
465 .ct_attrs = nvmet_ns_attrs,
466 .ct_owner = THIS_MODULE,
467};
468
469static struct config_group *nvmet_ns_make(struct config_group *group,
470 const char *name)
471{
472 struct nvmet_subsys *subsys = namespaces_to_subsys(&group->cg_item);
473 struct nvmet_ns *ns;
474 int ret;
475 u32 nsid;
476
477 ret = kstrtou32(name, 0, &nsid);
478 if (ret)
479 goto out;
480
481 ret = -EINVAL;
482 if (nsid == 0 || nsid == NVME_NSID_ALL)
483 goto out;
484
485 ret = -ENOMEM;
486 ns = nvmet_ns_alloc(subsys, nsid);
487 if (!ns)
488 goto out;
489 config_group_init_type_name(&ns->group, name, &nvmet_ns_type);
490
491 pr_info("adding nsid %d to subsystem %s\n", nsid, subsys->subsysnqn);
492
493 return &ns->group;
494out:
495 return ERR_PTR(ret);
496}
497
498static struct configfs_group_operations nvmet_namespaces_group_ops = {
499 .make_group = nvmet_ns_make,
500};
501
502static struct config_item_type nvmet_namespaces_type = {
503 .ct_group_ops = &nvmet_namespaces_group_ops,
504 .ct_owner = THIS_MODULE,
505};
506
507static int nvmet_port_subsys_allow_link(struct config_item *parent,
508 struct config_item *target)
509{
510 struct nvmet_port *port = to_nvmet_port(parent->ci_parent);
511 struct nvmet_subsys *subsys;
512 struct nvmet_subsys_link *link, *p;
513 int ret;
514
515 if (target->ci_type != &nvmet_subsys_type) {
516 pr_err("can only link subsystems into the subsystems dir.!\n");
517 return -EINVAL;
518 }
519 subsys = to_subsys(target);
520 link = kmalloc(sizeof(*link), GFP_KERNEL);
521 if (!link)
522 return -ENOMEM;
523 link->subsys = subsys;
524
525 down_write(&nvmet_config_sem);
526 ret = -EEXIST;
527 list_for_each_entry(p, &port->subsystems, entry) {
528 if (p->subsys == subsys)
529 goto out_free_link;
530 }
531
532 if (list_empty(&port->subsystems)) {
533 ret = nvmet_enable_port(port);
534 if (ret)
535 goto out_free_link;
536 }
537
538 list_add_tail(&link->entry, &port->subsystems);
539 nvmet_genctr++;
540 up_write(&nvmet_config_sem);
541 return 0;
542
543out_free_link:
544 up_write(&nvmet_config_sem);
545 kfree(link);
546 return ret;
547}
548
549static int nvmet_port_subsys_drop_link(struct config_item *parent,
550 struct config_item *target)
551{
552 struct nvmet_port *port = to_nvmet_port(parent->ci_parent);
553 struct nvmet_subsys *subsys = to_subsys(target);
554 struct nvmet_subsys_link *p;
555
556 down_write(&nvmet_config_sem);
557 list_for_each_entry(p, &port->subsystems, entry) {
558 if (p->subsys == subsys)
559 goto found;
560 }
561 up_write(&nvmet_config_sem);
562 return -EINVAL;
563
564found:
565 list_del(&p->entry);
566 nvmet_port_del_ctrls(port, subsys);
567 nvmet_genctr++;
568 if (list_empty(&port->subsystems))
569 nvmet_disable_port(port);
570 up_write(&nvmet_config_sem);
571 kfree(p);
572 return 0;
573}
574
575static struct configfs_item_operations nvmet_port_subsys_item_ops = {
576 .allow_link = nvmet_port_subsys_allow_link,
577 .drop_link = nvmet_port_subsys_drop_link,
578};
579
580static struct config_item_type nvmet_port_subsys_type = {
581 .ct_item_ops = &nvmet_port_subsys_item_ops,
582 .ct_owner = THIS_MODULE,
583};
584
585static int nvmet_allowed_hosts_allow_link(struct config_item *parent,
586 struct config_item *target)
587{
588 struct nvmet_subsys *subsys = to_subsys(parent->ci_parent);
589 struct nvmet_host *host;
590 struct nvmet_host_link *link, *p;
591 int ret;
592
593 if (target->ci_type != &nvmet_host_type) {
594 pr_err("can only link hosts into the allowed_hosts directory!\n");
595 return -EINVAL;
596 }
597
598 host = to_host(target);
599 link = kmalloc(sizeof(*link), GFP_KERNEL);
600 if (!link)
601 return -ENOMEM;
602 link->host = host;
603
604 down_write(&nvmet_config_sem);
605 ret = -EINVAL;
606 if (subsys->allow_any_host) {
607 pr_err("can't add hosts when allow_any_host is set!\n");
608 goto out_free_link;
609 }
610
611 ret = -EEXIST;
612 list_for_each_entry(p, &subsys->hosts, entry) {
613 if (!strcmp(nvmet_host_name(p->host), nvmet_host_name(host)))
614 goto out_free_link;
615 }
616 list_add_tail(&link->entry, &subsys->hosts);
617 nvmet_genctr++;
618 up_write(&nvmet_config_sem);
619 return 0;
620out_free_link:
621 up_write(&nvmet_config_sem);
622 kfree(link);
623 return ret;
624}
625
626static int nvmet_allowed_hosts_drop_link(struct config_item *parent,
627 struct config_item *target)
628{
629 struct nvmet_subsys *subsys = to_subsys(parent->ci_parent);
630 struct nvmet_host *host = to_host(target);
631 struct nvmet_host_link *p;
632
633 down_write(&nvmet_config_sem);
634 list_for_each_entry(p, &subsys->hosts, entry) {
635 if (!strcmp(nvmet_host_name(p->host), nvmet_host_name(host)))
636 goto found;
637 }
638 up_write(&nvmet_config_sem);
639 return -EINVAL;
640
641found:
642 list_del(&p->entry);
643 nvmet_genctr++;
644 up_write(&nvmet_config_sem);
645 kfree(p);
646 return 0;
647}
648
649static struct configfs_item_operations nvmet_allowed_hosts_item_ops = {
650 .allow_link = nvmet_allowed_hosts_allow_link,
651 .drop_link = nvmet_allowed_hosts_drop_link,
652};
653
654static struct config_item_type nvmet_allowed_hosts_type = {
655 .ct_item_ops = &nvmet_allowed_hosts_item_ops,
656 .ct_owner = THIS_MODULE,
657};
658
659static ssize_t nvmet_subsys_attr_allow_any_host_show(struct config_item *item,
660 char *page)
661{
662 return snprintf(page, PAGE_SIZE, "%d\n",
663 to_subsys(item)->allow_any_host);
664}
665
666static ssize_t nvmet_subsys_attr_allow_any_host_store(struct config_item *item,
667 const char *page, size_t count)
668{
669 struct nvmet_subsys *subsys = to_subsys(item);
670 bool allow_any_host;
671 int ret = 0;
672
673 if (strtobool(page, &allow_any_host))
674 return -EINVAL;
675
676 down_write(&nvmet_config_sem);
677 if (allow_any_host && !list_empty(&subsys->hosts)) {
678 pr_err("Can't set allow_any_host when explicit hosts are set!\n");
679 ret = -EINVAL;
680 goto out_unlock;
681 }
682
683 subsys->allow_any_host = allow_any_host;
684out_unlock:
685 up_write(&nvmet_config_sem);
686 return ret ? ret : count;
687}
688
689CONFIGFS_ATTR(nvmet_subsys_, attr_allow_any_host);
690
691static ssize_t nvmet_subsys_attr_version_show(struct config_item *item,
692 char *page)
693{
694 struct nvmet_subsys *subsys = to_subsys(item);
695
696 if (NVME_TERTIARY(subsys->ver))
697 return snprintf(page, PAGE_SIZE, "%d.%d.%d\n",
698 (int)NVME_MAJOR(subsys->ver),
699 (int)NVME_MINOR(subsys->ver),
700 (int)NVME_TERTIARY(subsys->ver));
701 else
702 return snprintf(page, PAGE_SIZE, "%d.%d\n",
703 (int)NVME_MAJOR(subsys->ver),
704 (int)NVME_MINOR(subsys->ver));
705}
706
707static ssize_t nvmet_subsys_attr_version_store(struct config_item *item,
708 const char *page, size_t count)
709{
710 struct nvmet_subsys *subsys = to_subsys(item);
711 int major, minor, tertiary = 0;
712 int ret;
713
714
715 ret = sscanf(page, "%d.%d.%d\n", &major, &minor, &tertiary);
716 if (ret != 2 && ret != 3)
717 return -EINVAL;
718
719 down_write(&nvmet_config_sem);
720 subsys->ver = NVME_VS(major, minor, tertiary);
721 up_write(&nvmet_config_sem);
722
723 return count;
724}
725CONFIGFS_ATTR(nvmet_subsys_, attr_version);
726
727static ssize_t nvmet_subsys_attr_serial_show(struct config_item *item,
728 char *page)
729{
730 struct nvmet_subsys *subsys = to_subsys(item);
731
732 return snprintf(page, PAGE_SIZE, "%llx\n", subsys->serial);
733}
734
735static ssize_t nvmet_subsys_attr_serial_store(struct config_item *item,
736 const char *page, size_t count)
737{
738 struct nvmet_subsys *subsys = to_subsys(item);
739
740 down_write(&nvmet_config_sem);
741 sscanf(page, "%llx\n", &subsys->serial);
742 up_write(&nvmet_config_sem);
743
744 return count;
745}
746CONFIGFS_ATTR(nvmet_subsys_, attr_serial);
747
748static struct configfs_attribute *nvmet_subsys_attrs[] = {
749 &nvmet_subsys_attr_attr_allow_any_host,
750 &nvmet_subsys_attr_attr_version,
751 &nvmet_subsys_attr_attr_serial,
752 NULL,
753};
754
755
756
757
758static void nvmet_subsys_release(struct config_item *item)
759{
760 struct nvmet_subsys *subsys = to_subsys(item);
761
762 nvmet_subsys_del_ctrls(subsys);
763 nvmet_subsys_put(subsys);
764}
765
766static struct configfs_item_operations nvmet_subsys_item_ops = {
767 .release = nvmet_subsys_release,
768};
769
770static struct config_item_type nvmet_subsys_type = {
771 .ct_item_ops = &nvmet_subsys_item_ops,
772 .ct_attrs = nvmet_subsys_attrs,
773 .ct_owner = THIS_MODULE,
774};
775
776static struct config_group *nvmet_subsys_make(struct config_group *group,
777 const char *name)
778{
779 struct nvmet_subsys *subsys;
780
781 if (sysfs_streq(name, NVME_DISC_SUBSYS_NAME)) {
782 pr_err("can't create discovery subsystem through configfs\n");
783 return ERR_PTR(-EINVAL);
784 }
785
786 subsys = nvmet_subsys_alloc(name, NVME_NQN_NVME);
787 if (IS_ERR(subsys))
788 return ERR_CAST(subsys);
789
790 config_group_init_type_name(&subsys->group, name, &nvmet_subsys_type);
791
792 config_group_init_type_name(&subsys->namespaces_group,
793 "namespaces", &nvmet_namespaces_type);
794 configfs_add_default_group(&subsys->namespaces_group, &subsys->group);
795
796 config_group_init_type_name(&subsys->allowed_hosts_group,
797 "allowed_hosts", &nvmet_allowed_hosts_type);
798 configfs_add_default_group(&subsys->allowed_hosts_group,
799 &subsys->group);
800
801 return &subsys->group;
802}
803
804static struct configfs_group_operations nvmet_subsystems_group_ops = {
805 .make_group = nvmet_subsys_make,
806};
807
808static struct config_item_type nvmet_subsystems_type = {
809 .ct_group_ops = &nvmet_subsystems_group_ops,
810 .ct_owner = THIS_MODULE,
811};
812
813static ssize_t nvmet_referral_enable_show(struct config_item *item,
814 char *page)
815{
816 return snprintf(page, PAGE_SIZE, "%d\n", to_nvmet_port(item)->enabled);
817}
818
819static ssize_t nvmet_referral_enable_store(struct config_item *item,
820 const char *page, size_t count)
821{
822 struct nvmet_port *parent = to_nvmet_port(item->ci_parent->ci_parent);
823 struct nvmet_port *port = to_nvmet_port(item);
824 bool enable;
825
826 if (strtobool(page, &enable))
827 goto inval;
828
829 if (enable)
830 nvmet_referral_enable(parent, port);
831 else
832 nvmet_referral_disable(port);
833
834 return count;
835inval:
836 pr_err("Invalid value '%s' for enable\n", page);
837 return -EINVAL;
838}
839
840CONFIGFS_ATTR(nvmet_referral_, enable);
841
842
843
844
845static struct configfs_attribute *nvmet_referral_attrs[] = {
846 &nvmet_attr_addr_adrfam,
847 &nvmet_attr_addr_portid,
848 &nvmet_attr_addr_treq,
849 &nvmet_attr_addr_traddr,
850 &nvmet_attr_addr_trsvcid,
851 &nvmet_attr_addr_trtype,
852 &nvmet_referral_attr_enable,
853 NULL,
854};
855
856static void nvmet_referral_release(struct config_item *item)
857{
858 struct nvmet_port *port = to_nvmet_port(item);
859
860 nvmet_referral_disable(port);
861 kfree(port);
862}
863
864static struct configfs_item_operations nvmet_referral_item_ops = {
865 .release = nvmet_referral_release,
866};
867
868static struct config_item_type nvmet_referral_type = {
869 .ct_owner = THIS_MODULE,
870 .ct_attrs = nvmet_referral_attrs,
871 .ct_item_ops = &nvmet_referral_item_ops,
872};
873
874static struct config_group *nvmet_referral_make(
875 struct config_group *group, const char *name)
876{
877 struct nvmet_port *port;
878
879 port = kzalloc(sizeof(*port), GFP_KERNEL);
880 if (!port)
881 return ERR_PTR(-ENOMEM);
882
883 INIT_LIST_HEAD(&port->entry);
884 config_group_init_type_name(&port->group, name, &nvmet_referral_type);
885
886 return &port->group;
887}
888
889static struct configfs_group_operations nvmet_referral_group_ops = {
890 .make_group = nvmet_referral_make,
891};
892
893static struct config_item_type nvmet_referrals_type = {
894 .ct_owner = THIS_MODULE,
895 .ct_group_ops = &nvmet_referral_group_ops,
896};
897
898
899
900
901static void nvmet_port_release(struct config_item *item)
902{
903 struct nvmet_port *port = to_nvmet_port(item);
904
905 kfree(port);
906}
907
908static struct configfs_attribute *nvmet_port_attrs[] = {
909 &nvmet_attr_addr_adrfam,
910 &nvmet_attr_addr_treq,
911 &nvmet_attr_addr_traddr,
912 &nvmet_attr_addr_trsvcid,
913 &nvmet_attr_addr_trtype,
914 &nvmet_attr_param_inline_data_size,
915 NULL,
916};
917
918static struct configfs_item_operations nvmet_port_item_ops = {
919 .release = nvmet_port_release,
920};
921
922static struct config_item_type nvmet_port_type = {
923 .ct_attrs = nvmet_port_attrs,
924 .ct_item_ops = &nvmet_port_item_ops,
925 .ct_owner = THIS_MODULE,
926};
927
928static struct config_group *nvmet_ports_make(struct config_group *group,
929 const char *name)
930{
931 struct nvmet_port *port;
932 u16 portid;
933
934 if (kstrtou16(name, 0, &portid))
935 return ERR_PTR(-EINVAL);
936
937 port = kzalloc(sizeof(*port), GFP_KERNEL);
938 if (!port)
939 return ERR_PTR(-ENOMEM);
940
941 INIT_LIST_HEAD(&port->entry);
942 INIT_LIST_HEAD(&port->subsystems);
943 INIT_LIST_HEAD(&port->referrals);
944 port->inline_data_size = -1;
945
946 port->disc_addr.portid = cpu_to_le16(portid);
947 config_group_init_type_name(&port->group, name, &nvmet_port_type);
948
949 config_group_init_type_name(&port->subsys_group,
950 "subsystems", &nvmet_port_subsys_type);
951 configfs_add_default_group(&port->subsys_group, &port->group);
952
953 config_group_init_type_name(&port->referrals_group,
954 "referrals", &nvmet_referrals_type);
955 configfs_add_default_group(&port->referrals_group, &port->group);
956
957 return &port->group;
958}
959
960static struct configfs_group_operations nvmet_ports_group_ops = {
961 .make_group = nvmet_ports_make,
962};
963
964static struct config_item_type nvmet_ports_type = {
965 .ct_group_ops = &nvmet_ports_group_ops,
966 .ct_owner = THIS_MODULE,
967};
968
969static struct config_group nvmet_subsystems_group;
970static struct config_group nvmet_ports_group;
971
972static void nvmet_host_release(struct config_item *item)
973{
974 struct nvmet_host *host = to_host(item);
975
976 kfree(host);
977}
978
979static struct configfs_item_operations nvmet_host_item_ops = {
980 .release = nvmet_host_release,
981};
982
983static struct config_item_type nvmet_host_type = {
984 .ct_item_ops = &nvmet_host_item_ops,
985 .ct_owner = THIS_MODULE,
986};
987
988static struct config_group *nvmet_hosts_make_group(struct config_group *group,
989 const char *name)
990{
991 struct nvmet_host *host;
992
993 host = kzalloc(sizeof(*host), GFP_KERNEL);
994 if (!host)
995 return ERR_PTR(-ENOMEM);
996
997 config_group_init_type_name(&host->group, name, &nvmet_host_type);
998
999 return &host->group;
1000}
1001
1002static struct configfs_group_operations nvmet_hosts_group_ops = {
1003 .make_group = nvmet_hosts_make_group,
1004};
1005
1006static struct config_item_type nvmet_hosts_type = {
1007 .ct_group_ops = &nvmet_hosts_group_ops,
1008 .ct_owner = THIS_MODULE,
1009};
1010
1011static struct config_group nvmet_hosts_group;
1012
1013static struct config_item_type nvmet_root_type = {
1014 .ct_owner = THIS_MODULE,
1015};
1016
1017static struct configfs_subsystem nvmet_configfs_subsystem = {
1018 .su_group = {
1019 .cg_item = {
1020 .ci_namebuf = "nvmet",
1021 .ci_type = &nvmet_root_type,
1022 },
1023 },
1024};
1025
1026int __init nvmet_init_configfs(void)
1027{
1028 int ret;
1029
1030 config_group_init(&nvmet_configfs_subsystem.su_group);
1031 mutex_init(&nvmet_configfs_subsystem.su_mutex);
1032
1033 config_group_init_type_name(&nvmet_subsystems_group,
1034 "subsystems", &nvmet_subsystems_type);
1035 configfs_add_default_group(&nvmet_subsystems_group,
1036 &nvmet_configfs_subsystem.su_group);
1037
1038 config_group_init_type_name(&nvmet_ports_group,
1039 "ports", &nvmet_ports_type);
1040 configfs_add_default_group(&nvmet_ports_group,
1041 &nvmet_configfs_subsystem.su_group);
1042
1043 config_group_init_type_name(&nvmet_hosts_group,
1044 "hosts", &nvmet_hosts_type);
1045 configfs_add_default_group(&nvmet_hosts_group,
1046 &nvmet_configfs_subsystem.su_group);
1047
1048 ret = configfs_register_subsystem(&nvmet_configfs_subsystem);
1049 if (ret) {
1050 pr_err("configfs_register_subsystem: %d\n", ret);
1051 return ret;
1052 }
1053
1054 return 0;
1055}
1056
1057void __exit nvmet_exit_configfs(void)
1058{
1059 configfs_unregister_subsystem(&nvmet_configfs_subsystem);
1060}
1061