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