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