Merge branch 'l1tf-final' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
[linux] / drivers / nvme / target / configfs.c
1 /*
2  * Configfs interface for the NVMe target.
3  * Copyright (c) 2015-2016 HGST, a Western Digital Company.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  */
14 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/slab.h>
18 #include <linux/stat.h>
19 #include <linux/ctype.h>
20
21 #include "nvmet.h"
22
23 static const struct config_item_type nvmet_host_type;
24 static const struct config_item_type nvmet_subsys_type;
25
26 static 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  * nvmet_port Generic ConfigFS definitions.
37  * Used in any place in the ConfigFS tree that refers to an address.
38  */
39 static 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
56 static 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
83 CONFIGFS_ATTR(nvmet_, addr_adrfam);
84
85 static 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
94 static 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
114 CONFIGFS_ATTR(nvmet_, addr_portid);
115
116 static 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
125 static 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
146 CONFIGFS_ATTR(nvmet_, addr_traddr);
147
148 static 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
163 static 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
188 CONFIGFS_ATTR(nvmet_, addr_treq);
189
190 static 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
199 static 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
219 CONFIGFS_ATTR(nvmet_, addr_trsvcid);
220
221 static ssize_t nvmet_addr_trtype_show(struct config_item *item,
222                 char *page)
223 {
224         struct nvmet_port *port = to_nvmet_port(item);
225         int i;
226
227         for (i = 0; i < ARRAY_SIZE(nvmet_transport_names); i++) {
228                 if (port->disc_addr.trtype != nvmet_transport_names[i].type)
229                         continue;
230                 return sprintf(page, "%s\n", nvmet_transport_names[i].name);
231         }
232
233         return sprintf(page, "\n");
234 }
235
236 static void nvmet_port_init_tsas_rdma(struct nvmet_port *port)
237 {
238         port->disc_addr.tsas.rdma.qptype = NVMF_RDMA_QPTYPE_CONNECTED;
239         port->disc_addr.tsas.rdma.prtype = NVMF_RDMA_PRTYPE_NOT_SPECIFIED;
240         port->disc_addr.tsas.rdma.cms = NVMF_RDMA_CMS_RDMA_CM;
241 }
242
243 static ssize_t nvmet_addr_trtype_store(struct config_item *item,
244                 const char *page, size_t count)
245 {
246         struct nvmet_port *port = to_nvmet_port(item);
247         int i;
248
249         if (port->enabled) {
250                 pr_err("Cannot modify address while enabled\n");
251                 pr_err("Disable the address before modifying\n");
252                 return -EACCES;
253         }
254
255         for (i = 0; i < ARRAY_SIZE(nvmet_transport_names); i++) {
256                 if (sysfs_streq(page, nvmet_transport_names[i].name))
257                         goto found;
258         }
259
260         pr_err("Invalid value '%s' for trtype\n", page);
261         return -EINVAL;
262 found:
263         memset(&port->disc_addr.tsas, 0, NVMF_TSAS_SIZE);
264         port->disc_addr.trtype = nvmet_transport_names[i].type;
265         if (port->disc_addr.trtype == NVMF_TRTYPE_RDMA)
266                 nvmet_port_init_tsas_rdma(port);
267         return count;
268 }
269
270 CONFIGFS_ATTR(nvmet_, addr_trtype);
271
272 /*
273  * Namespace structures & file operation functions below
274  */
275 static ssize_t nvmet_ns_device_path_show(struct config_item *item, char *page)
276 {
277         return sprintf(page, "%s\n", to_nvmet_ns(item)->device_path);
278 }
279
280 static ssize_t nvmet_ns_device_path_store(struct config_item *item,
281                 const char *page, size_t count)
282 {
283         struct nvmet_ns *ns = to_nvmet_ns(item);
284         struct nvmet_subsys *subsys = ns->subsys;
285         size_t len;
286         int ret;
287
288         mutex_lock(&subsys->lock);
289         ret = -EBUSY;
290         if (ns->enabled)
291                 goto out_unlock;
292
293         ret = -EINVAL;
294         len = strcspn(page, "\n");
295         if (!len)
296                 goto out_unlock;
297
298         kfree(ns->device_path);
299         ret = -ENOMEM;
300         ns->device_path = kstrndup(page, len, GFP_KERNEL);
301         if (!ns->device_path)
302                 goto out_unlock;
303
304         mutex_unlock(&subsys->lock);
305         return count;
306
307 out_unlock:
308         mutex_unlock(&subsys->lock);
309         return ret;
310 }
311
312 CONFIGFS_ATTR(nvmet_ns_, device_path);
313
314 static ssize_t nvmet_ns_device_uuid_show(struct config_item *item, char *page)
315 {
316         return sprintf(page, "%pUb\n", &to_nvmet_ns(item)->uuid);
317 }
318
319 static ssize_t nvmet_ns_device_uuid_store(struct config_item *item,
320                                           const char *page, size_t count)
321 {
322         struct nvmet_ns *ns = to_nvmet_ns(item);
323         struct nvmet_subsys *subsys = ns->subsys;
324         int ret = 0;
325
326
327         mutex_lock(&subsys->lock);
328         if (ns->enabled) {
329                 ret = -EBUSY;
330                 goto out_unlock;
331         }
332
333
334         if (uuid_parse(page, &ns->uuid))
335                 ret = -EINVAL;
336
337 out_unlock:
338         mutex_unlock(&subsys->lock);
339         return ret ? ret : count;
340 }
341
342 CONFIGFS_ATTR(nvmet_ns_, device_uuid);
343
344 static ssize_t nvmet_ns_device_nguid_show(struct config_item *item, char *page)
345 {
346         return sprintf(page, "%pUb\n", &to_nvmet_ns(item)->nguid);
347 }
348
349 static ssize_t nvmet_ns_device_nguid_store(struct config_item *item,
350                 const char *page, size_t count)
351 {
352         struct nvmet_ns *ns = to_nvmet_ns(item);
353         struct nvmet_subsys *subsys = ns->subsys;
354         u8 nguid[16];
355         const char *p = page;
356         int i;
357         int ret = 0;
358
359         mutex_lock(&subsys->lock);
360         if (ns->enabled) {
361                 ret = -EBUSY;
362                 goto out_unlock;
363         }
364
365         for (i = 0; i < 16; i++) {
366                 if (p + 2 > page + count) {
367                         ret = -EINVAL;
368                         goto out_unlock;
369                 }
370                 if (!isxdigit(p[0]) || !isxdigit(p[1])) {
371                         ret = -EINVAL;
372                         goto out_unlock;
373                 }
374
375                 nguid[i] = (hex_to_bin(p[0]) << 4) | hex_to_bin(p[1]);
376                 p += 2;
377
378                 if (*p == '-' || *p == ':')
379                         p++;
380         }
381
382         memcpy(&ns->nguid, nguid, sizeof(nguid));
383 out_unlock:
384         mutex_unlock(&subsys->lock);
385         return ret ? ret : count;
386 }
387
388 CONFIGFS_ATTR(nvmet_ns_, device_nguid);
389
390 static ssize_t nvmet_ns_enable_show(struct config_item *item, char *page)
391 {
392         return sprintf(page, "%d\n", to_nvmet_ns(item)->enabled);
393 }
394
395 static ssize_t nvmet_ns_enable_store(struct config_item *item,
396                 const char *page, size_t count)
397 {
398         struct nvmet_ns *ns = to_nvmet_ns(item);
399         bool enable;
400         int ret = 0;
401
402         if (strtobool(page, &enable))
403                 return -EINVAL;
404
405         if (enable)
406                 ret = nvmet_ns_enable(ns);
407         else
408                 nvmet_ns_disable(ns);
409
410         return ret ? ret : count;
411 }
412
413 CONFIGFS_ATTR(nvmet_ns_, enable);
414
415 static struct configfs_attribute *nvmet_ns_attrs[] = {
416         &nvmet_ns_attr_device_path,
417         &nvmet_ns_attr_device_nguid,
418         &nvmet_ns_attr_device_uuid,
419         &nvmet_ns_attr_enable,
420         NULL,
421 };
422
423 static void nvmet_ns_release(struct config_item *item)
424 {
425         struct nvmet_ns *ns = to_nvmet_ns(item);
426
427         nvmet_ns_free(ns);
428 }
429
430 static struct configfs_item_operations nvmet_ns_item_ops = {
431         .release                = nvmet_ns_release,
432 };
433
434 static const struct config_item_type nvmet_ns_type = {
435         .ct_item_ops            = &nvmet_ns_item_ops,
436         .ct_attrs               = nvmet_ns_attrs,
437         .ct_owner               = THIS_MODULE,
438 };
439
440 static struct config_group *nvmet_ns_make(struct config_group *group,
441                 const char *name)
442 {
443         struct nvmet_subsys *subsys = namespaces_to_subsys(&group->cg_item);
444         struct nvmet_ns *ns;
445         int ret;
446         u32 nsid;
447
448         ret = kstrtou32(name, 0, &nsid);
449         if (ret)
450                 goto out;
451
452         ret = -EINVAL;
453         if (nsid == 0 || nsid == NVME_NSID_ALL)
454                 goto out;
455
456         ret = -ENOMEM;
457         ns = nvmet_ns_alloc(subsys, nsid);
458         if (!ns)
459                 goto out;
460         config_group_init_type_name(&ns->group, name, &nvmet_ns_type);
461
462         pr_info("adding nsid %d to subsystem %s\n", nsid, subsys->subsysnqn);
463
464         return &ns->group;
465 out:
466         return ERR_PTR(ret);
467 }
468
469 static struct configfs_group_operations nvmet_namespaces_group_ops = {
470         .make_group             = nvmet_ns_make,
471 };
472
473 static const struct config_item_type nvmet_namespaces_type = {
474         .ct_group_ops           = &nvmet_namespaces_group_ops,
475         .ct_owner               = THIS_MODULE,
476 };
477
478 static int nvmet_port_subsys_allow_link(struct config_item *parent,
479                 struct config_item *target)
480 {
481         struct nvmet_port *port = to_nvmet_port(parent->ci_parent);
482         struct nvmet_subsys *subsys;
483         struct nvmet_subsys_link *link, *p;
484         int ret;
485
486         if (target->ci_type != &nvmet_subsys_type) {
487                 pr_err("can only link subsystems into the subsystems dir.!\n");
488                 return -EINVAL;
489         }
490         subsys = to_subsys(target);
491         link = kmalloc(sizeof(*link), GFP_KERNEL);
492         if (!link)
493                 return -ENOMEM;
494         link->subsys = subsys;
495
496         down_write(&nvmet_config_sem);
497         ret = -EEXIST;
498         list_for_each_entry(p, &port->subsystems, entry) {
499                 if (p->subsys == subsys)
500                         goto out_free_link;
501         }
502
503         if (list_empty(&port->subsystems)) {
504                 ret = nvmet_enable_port(port);
505                 if (ret)
506                         goto out_free_link;
507         }
508
509         list_add_tail(&link->entry, &port->subsystems);
510         nvmet_genctr++;
511         up_write(&nvmet_config_sem);
512         return 0;
513
514 out_free_link:
515         up_write(&nvmet_config_sem);
516         kfree(link);
517         return ret;
518 }
519
520 static void nvmet_port_subsys_drop_link(struct config_item *parent,
521                 struct config_item *target)
522 {
523         struct nvmet_port *port = to_nvmet_port(parent->ci_parent);
524         struct nvmet_subsys *subsys = to_subsys(target);
525         struct nvmet_subsys_link *p;
526
527         down_write(&nvmet_config_sem);
528         list_for_each_entry(p, &port->subsystems, entry) {
529                 if (p->subsys == subsys)
530                         goto found;
531         }
532         up_write(&nvmet_config_sem);
533         return;
534
535 found:
536         list_del(&p->entry);
537         nvmet_genctr++;
538         if (list_empty(&port->subsystems))
539                 nvmet_disable_port(port);
540         up_write(&nvmet_config_sem);
541         kfree(p);
542 }
543
544 static struct configfs_item_operations nvmet_port_subsys_item_ops = {
545         .allow_link             = nvmet_port_subsys_allow_link,
546         .drop_link              = nvmet_port_subsys_drop_link,
547 };
548
549 static const struct config_item_type nvmet_port_subsys_type = {
550         .ct_item_ops            = &nvmet_port_subsys_item_ops,
551         .ct_owner               = THIS_MODULE,
552 };
553
554 static int nvmet_allowed_hosts_allow_link(struct config_item *parent,
555                 struct config_item *target)
556 {
557         struct nvmet_subsys *subsys = to_subsys(parent->ci_parent);
558         struct nvmet_host *host;
559         struct nvmet_host_link *link, *p;
560         int ret;
561
562         if (target->ci_type != &nvmet_host_type) {
563                 pr_err("can only link hosts into the allowed_hosts directory!\n");
564                 return -EINVAL;
565         }
566
567         host = to_host(target);
568         link = kmalloc(sizeof(*link), GFP_KERNEL);
569         if (!link)
570                 return -ENOMEM;
571         link->host = host;
572
573         down_write(&nvmet_config_sem);
574         ret = -EINVAL;
575         if (subsys->allow_any_host) {
576                 pr_err("can't add hosts when allow_any_host is set!\n");
577                 goto out_free_link;
578         }
579
580         ret = -EEXIST;
581         list_for_each_entry(p, &subsys->hosts, entry) {
582                 if (!strcmp(nvmet_host_name(p->host), nvmet_host_name(host)))
583                         goto out_free_link;
584         }
585         list_add_tail(&link->entry, &subsys->hosts);
586         nvmet_genctr++;
587         up_write(&nvmet_config_sem);
588         return 0;
589 out_free_link:
590         up_write(&nvmet_config_sem);
591         kfree(link);
592         return ret;
593 }
594
595 static void nvmet_allowed_hosts_drop_link(struct config_item *parent,
596                 struct config_item *target)
597 {
598         struct nvmet_subsys *subsys = to_subsys(parent->ci_parent);
599         struct nvmet_host *host = to_host(target);
600         struct nvmet_host_link *p;
601
602         down_write(&nvmet_config_sem);
603         list_for_each_entry(p, &subsys->hosts, entry) {
604                 if (!strcmp(nvmet_host_name(p->host), nvmet_host_name(host)))
605                         goto found;
606         }
607         up_write(&nvmet_config_sem);
608         return;
609
610 found:
611         list_del(&p->entry);
612         nvmet_genctr++;
613         up_write(&nvmet_config_sem);
614         kfree(p);
615 }
616
617 static struct configfs_item_operations nvmet_allowed_hosts_item_ops = {
618         .allow_link             = nvmet_allowed_hosts_allow_link,
619         .drop_link              = nvmet_allowed_hosts_drop_link,
620 };
621
622 static const struct config_item_type nvmet_allowed_hosts_type = {
623         .ct_item_ops            = &nvmet_allowed_hosts_item_ops,
624         .ct_owner               = THIS_MODULE,
625 };
626
627 static ssize_t nvmet_subsys_attr_allow_any_host_show(struct config_item *item,
628                 char *page)
629 {
630         return snprintf(page, PAGE_SIZE, "%d\n",
631                 to_subsys(item)->allow_any_host);
632 }
633
634 static ssize_t nvmet_subsys_attr_allow_any_host_store(struct config_item *item,
635                 const char *page, size_t count)
636 {
637         struct nvmet_subsys *subsys = to_subsys(item);
638         bool allow_any_host;
639         int ret = 0;
640
641         if (strtobool(page, &allow_any_host))
642                 return -EINVAL;
643
644         down_write(&nvmet_config_sem);
645         if (allow_any_host && !list_empty(&subsys->hosts)) {
646                 pr_err("Can't set allow_any_host when explicit hosts are set!\n");
647                 ret = -EINVAL;
648                 goto out_unlock;
649         }
650
651         subsys->allow_any_host = allow_any_host;
652 out_unlock:
653         up_write(&nvmet_config_sem);
654         return ret ? ret : count;
655 }
656
657 CONFIGFS_ATTR(nvmet_subsys_, attr_allow_any_host);
658
659 static ssize_t nvmet_subsys_attr_version_show(struct config_item *item,
660                                               char *page)
661 {
662         struct nvmet_subsys *subsys = to_subsys(item);
663
664         if (NVME_TERTIARY(subsys->ver))
665                 return snprintf(page, PAGE_SIZE, "%d.%d.%d\n",
666                                 (int)NVME_MAJOR(subsys->ver),
667                                 (int)NVME_MINOR(subsys->ver),
668                                 (int)NVME_TERTIARY(subsys->ver));
669         else
670                 return snprintf(page, PAGE_SIZE, "%d.%d\n",
671                                 (int)NVME_MAJOR(subsys->ver),
672                                 (int)NVME_MINOR(subsys->ver));
673 }
674
675 static ssize_t nvmet_subsys_attr_version_store(struct config_item *item,
676                                                const char *page, size_t count)
677 {
678         struct nvmet_subsys *subsys = to_subsys(item);
679         int major, minor, tertiary = 0;
680         int ret;
681
682
683         ret = sscanf(page, "%d.%d.%d\n", &major, &minor, &tertiary);
684         if (ret != 2 && ret != 3)
685                 return -EINVAL;
686
687         down_write(&nvmet_config_sem);
688         subsys->ver = NVME_VS(major, minor, tertiary);
689         up_write(&nvmet_config_sem);
690
691         return count;
692 }
693 CONFIGFS_ATTR(nvmet_subsys_, attr_version);
694
695 static ssize_t nvmet_subsys_attr_serial_show(struct config_item *item,
696                                              char *page)
697 {
698         struct nvmet_subsys *subsys = to_subsys(item);
699
700         return snprintf(page, PAGE_SIZE, "%llx\n", subsys->serial);
701 }
702
703 static ssize_t nvmet_subsys_attr_serial_store(struct config_item *item,
704                                               const char *page, size_t count)
705 {
706         struct nvmet_subsys *subsys = to_subsys(item);
707
708         down_write(&nvmet_config_sem);
709         sscanf(page, "%llx\n", &subsys->serial);
710         up_write(&nvmet_config_sem);
711
712         return count;
713 }
714 CONFIGFS_ATTR(nvmet_subsys_, attr_serial);
715
716 static struct configfs_attribute *nvmet_subsys_attrs[] = {
717         &nvmet_subsys_attr_attr_allow_any_host,
718         &nvmet_subsys_attr_attr_version,
719         &nvmet_subsys_attr_attr_serial,
720         NULL,
721 };
722
723 /*
724  * Subsystem structures & folder operation functions below
725  */
726 static void nvmet_subsys_release(struct config_item *item)
727 {
728         struct nvmet_subsys *subsys = to_subsys(item);
729
730         nvmet_subsys_del_ctrls(subsys);
731         nvmet_subsys_put(subsys);
732 }
733
734 static struct configfs_item_operations nvmet_subsys_item_ops = {
735         .release                = nvmet_subsys_release,
736 };
737
738 static const struct config_item_type nvmet_subsys_type = {
739         .ct_item_ops            = &nvmet_subsys_item_ops,
740         .ct_attrs               = nvmet_subsys_attrs,
741         .ct_owner               = THIS_MODULE,
742 };
743
744 static struct config_group *nvmet_subsys_make(struct config_group *group,
745                 const char *name)
746 {
747         struct nvmet_subsys *subsys;
748
749         if (sysfs_streq(name, NVME_DISC_SUBSYS_NAME)) {
750                 pr_err("can't create discovery subsystem through configfs\n");
751                 return ERR_PTR(-EINVAL);
752         }
753
754         subsys = nvmet_subsys_alloc(name, NVME_NQN_NVME);
755         if (!subsys)
756                 return ERR_PTR(-ENOMEM);
757
758         config_group_init_type_name(&subsys->group, name, &nvmet_subsys_type);
759
760         config_group_init_type_name(&subsys->namespaces_group,
761                         "namespaces", &nvmet_namespaces_type);
762         configfs_add_default_group(&subsys->namespaces_group, &subsys->group);
763
764         config_group_init_type_name(&subsys->allowed_hosts_group,
765                         "allowed_hosts", &nvmet_allowed_hosts_type);
766         configfs_add_default_group(&subsys->allowed_hosts_group,
767                         &subsys->group);
768
769         return &subsys->group;
770 }
771
772 static struct configfs_group_operations nvmet_subsystems_group_ops = {
773         .make_group             = nvmet_subsys_make,
774 };
775
776 static const struct config_item_type nvmet_subsystems_type = {
777         .ct_group_ops           = &nvmet_subsystems_group_ops,
778         .ct_owner               = THIS_MODULE,
779 };
780
781 static ssize_t nvmet_referral_enable_show(struct config_item *item,
782                 char *page)
783 {
784         return snprintf(page, PAGE_SIZE, "%d\n", to_nvmet_port(item)->enabled);
785 }
786
787 static ssize_t nvmet_referral_enable_store(struct config_item *item,
788                 const char *page, size_t count)
789 {
790         struct nvmet_port *parent = to_nvmet_port(item->ci_parent->ci_parent);
791         struct nvmet_port *port = to_nvmet_port(item);
792         bool enable;
793
794         if (strtobool(page, &enable))
795                 goto inval;
796
797         if (enable)
798                 nvmet_referral_enable(parent, port);
799         else
800                 nvmet_referral_disable(port);
801
802         return count;
803 inval:
804         pr_err("Invalid value '%s' for enable\n", page);
805         return -EINVAL;
806 }
807
808 CONFIGFS_ATTR(nvmet_referral_, enable);
809
810 /*
811  * Discovery Service subsystem definitions
812  */
813 static struct configfs_attribute *nvmet_referral_attrs[] = {
814         &nvmet_attr_addr_adrfam,
815         &nvmet_attr_addr_portid,
816         &nvmet_attr_addr_treq,
817         &nvmet_attr_addr_traddr,
818         &nvmet_attr_addr_trsvcid,
819         &nvmet_attr_addr_trtype,
820         &nvmet_referral_attr_enable,
821         NULL,
822 };
823
824 static void nvmet_referral_release(struct config_item *item)
825 {
826         struct nvmet_port *port = to_nvmet_port(item);
827
828         nvmet_referral_disable(port);
829         kfree(port);
830 }
831
832 static struct configfs_item_operations nvmet_referral_item_ops = {
833         .release        = nvmet_referral_release,
834 };
835
836 static const struct config_item_type nvmet_referral_type = {
837         .ct_owner       = THIS_MODULE,
838         .ct_attrs       = nvmet_referral_attrs,
839         .ct_item_ops    = &nvmet_referral_item_ops,
840 };
841
842 static struct config_group *nvmet_referral_make(
843                 struct config_group *group, const char *name)
844 {
845         struct nvmet_port *port;
846
847         port = kzalloc(sizeof(*port), GFP_KERNEL);
848         if (!port)
849                 return ERR_PTR(-ENOMEM);
850
851         INIT_LIST_HEAD(&port->entry);
852         config_group_init_type_name(&port->group, name, &nvmet_referral_type);
853
854         return &port->group;
855 }
856
857 static struct configfs_group_operations nvmet_referral_group_ops = {
858         .make_group             = nvmet_referral_make,
859 };
860
861 static const struct config_item_type nvmet_referrals_type = {
862         .ct_owner       = THIS_MODULE,
863         .ct_group_ops   = &nvmet_referral_group_ops,
864 };
865
866 /*
867  * Ports definitions.
868  */
869 static void nvmet_port_release(struct config_item *item)
870 {
871         struct nvmet_port *port = to_nvmet_port(item);
872
873         kfree(port);
874 }
875
876 static struct configfs_attribute *nvmet_port_attrs[] = {
877         &nvmet_attr_addr_adrfam,
878         &nvmet_attr_addr_treq,
879         &nvmet_attr_addr_traddr,
880         &nvmet_attr_addr_trsvcid,
881         &nvmet_attr_addr_trtype,
882         NULL,
883 };
884
885 static struct configfs_item_operations nvmet_port_item_ops = {
886         .release                = nvmet_port_release,
887 };
888
889 static const struct config_item_type nvmet_port_type = {
890         .ct_attrs               = nvmet_port_attrs,
891         .ct_item_ops            = &nvmet_port_item_ops,
892         .ct_owner               = THIS_MODULE,
893 };
894
895 static struct config_group *nvmet_ports_make(struct config_group *group,
896                 const char *name)
897 {
898         struct nvmet_port *port;
899         u16 portid;
900
901         if (kstrtou16(name, 0, &portid))
902                 return ERR_PTR(-EINVAL);
903
904         port = kzalloc(sizeof(*port), GFP_KERNEL);
905         if (!port)
906                 return ERR_PTR(-ENOMEM);
907
908         INIT_LIST_HEAD(&port->entry);
909         INIT_LIST_HEAD(&port->subsystems);
910         INIT_LIST_HEAD(&port->referrals);
911
912         port->disc_addr.portid = cpu_to_le16(portid);
913         config_group_init_type_name(&port->group, name, &nvmet_port_type);
914
915         config_group_init_type_name(&port->subsys_group,
916                         "subsystems", &nvmet_port_subsys_type);
917         configfs_add_default_group(&port->subsys_group, &port->group);
918
919         config_group_init_type_name(&port->referrals_group,
920                         "referrals", &nvmet_referrals_type);
921         configfs_add_default_group(&port->referrals_group, &port->group);
922
923         return &port->group;
924 }
925
926 static struct configfs_group_operations nvmet_ports_group_ops = {
927         .make_group             = nvmet_ports_make,
928 };
929
930 static const struct config_item_type nvmet_ports_type = {
931         .ct_group_ops           = &nvmet_ports_group_ops,
932         .ct_owner               = THIS_MODULE,
933 };
934
935 static struct config_group nvmet_subsystems_group;
936 static struct config_group nvmet_ports_group;
937
938 static void nvmet_host_release(struct config_item *item)
939 {
940         struct nvmet_host *host = to_host(item);
941
942         kfree(host);
943 }
944
945 static struct configfs_item_operations nvmet_host_item_ops = {
946         .release                = nvmet_host_release,
947 };
948
949 static const struct config_item_type nvmet_host_type = {
950         .ct_item_ops            = &nvmet_host_item_ops,
951         .ct_owner               = THIS_MODULE,
952 };
953
954 static struct config_group *nvmet_hosts_make_group(struct config_group *group,
955                 const char *name)
956 {
957         struct nvmet_host *host;
958
959         host = kzalloc(sizeof(*host), GFP_KERNEL);
960         if (!host)
961                 return ERR_PTR(-ENOMEM);
962
963         config_group_init_type_name(&host->group, name, &nvmet_host_type);
964
965         return &host->group;
966 }
967
968 static struct configfs_group_operations nvmet_hosts_group_ops = {
969         .make_group             = nvmet_hosts_make_group,
970 };
971
972 static const struct config_item_type nvmet_hosts_type = {
973         .ct_group_ops           = &nvmet_hosts_group_ops,
974         .ct_owner               = THIS_MODULE,
975 };
976
977 static struct config_group nvmet_hosts_group;
978
979 static const struct config_item_type nvmet_root_type = {
980         .ct_owner               = THIS_MODULE,
981 };
982
983 static struct configfs_subsystem nvmet_configfs_subsystem = {
984         .su_group = {
985                 .cg_item = {
986                         .ci_namebuf     = "nvmet",
987                         .ci_type        = &nvmet_root_type,
988                 },
989         },
990 };
991
992 int __init nvmet_init_configfs(void)
993 {
994         int ret;
995
996         config_group_init(&nvmet_configfs_subsystem.su_group);
997         mutex_init(&nvmet_configfs_subsystem.su_mutex);
998
999         config_group_init_type_name(&nvmet_subsystems_group,
1000                         "subsystems", &nvmet_subsystems_type);
1001         configfs_add_default_group(&nvmet_subsystems_group,
1002                         &nvmet_configfs_subsystem.su_group);
1003
1004         config_group_init_type_name(&nvmet_ports_group,
1005                         "ports", &nvmet_ports_type);
1006         configfs_add_default_group(&nvmet_ports_group,
1007                         &nvmet_configfs_subsystem.su_group);
1008
1009         config_group_init_type_name(&nvmet_hosts_group,
1010                         "hosts", &nvmet_hosts_type);
1011         configfs_add_default_group(&nvmet_hosts_group,
1012                         &nvmet_configfs_subsystem.su_group);
1013
1014         ret = configfs_register_subsystem(&nvmet_configfs_subsystem);
1015         if (ret) {
1016                 pr_err("configfs_register_subsystem: %d\n", ret);
1017                 return ret;
1018         }
1019
1020         return 0;
1021 }
1022
1023 void __exit nvmet_exit_configfs(void)
1024 {
1025         configfs_unregister_subsystem(&nvmet_configfs_subsystem);
1026 }