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