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