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