xref: /openbmc/linux/drivers/nvme/target/configfs.c (revision f79e4d5f92a129a1159c973735007d4ddc8541f3)
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 }
1027