nvmet: don't override treq upon modification.
[linux-block.git] / drivers / nvme / target / configfs.c
CommitLineData
a07b4970
CH
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>
c6925093
LG
20#include <linux/pci.h>
21#include <linux/pci-p2pdma.h>
a07b4970
CH
22
23#include "nvmet.h"
24
66603a31
BG
25static const struct config_item_type nvmet_host_type;
26static const struct config_item_type nvmet_subsys_type;
a07b4970 27
b662a078
JS
28static LIST_HEAD(nvmet_ports_list);
29struct list_head *nvmet_ports = &nvmet_ports_list;
30
a5d18612
CH
31static const struct nvmet_transport_name {
32 u8 type;
33 const char *name;
34} nvmet_transport_names[] = {
35 { NVMF_TRTYPE_RDMA, "rdma" },
36 { NVMF_TRTYPE_FC, "fc" },
37 { NVMF_TRTYPE_LOOP, "loop" },
38};
39
a07b4970
CH
40/*
41 * nvmet_port Generic ConfigFS definitions.
42 * Used in any place in the ConfigFS tree that refers to an address.
43 */
44static ssize_t nvmet_addr_adrfam_show(struct config_item *item,
45 char *page)
46{
47 switch (to_nvmet_port(item)->disc_addr.adrfam) {
48 case NVMF_ADDR_FAMILY_IP4:
49 return sprintf(page, "ipv4\n");
50 case NVMF_ADDR_FAMILY_IP6:
51 return sprintf(page, "ipv6\n");
52 case NVMF_ADDR_FAMILY_IB:
53 return sprintf(page, "ib\n");
885aa401
JS
54 case NVMF_ADDR_FAMILY_FC:
55 return sprintf(page, "fc\n");
a07b4970
CH
56 default:
57 return sprintf(page, "\n");
58 }
59}
60
61static ssize_t nvmet_addr_adrfam_store(struct config_item *item,
62 const char *page, size_t count)
63{
64 struct nvmet_port *port = to_nvmet_port(item);
65
66 if (port->enabled) {
67 pr_err("Cannot modify address while enabled\n");
68 pr_err("Disable the address before modifying\n");
69 return -EACCES;
70 }
71
72 if (sysfs_streq(page, "ipv4")) {
73 port->disc_addr.adrfam = NVMF_ADDR_FAMILY_IP4;
74 } else if (sysfs_streq(page, "ipv6")) {
75 port->disc_addr.adrfam = NVMF_ADDR_FAMILY_IP6;
76 } else if (sysfs_streq(page, "ib")) {
77 port->disc_addr.adrfam = NVMF_ADDR_FAMILY_IB;
885aa401
JS
78 } else if (sysfs_streq(page, "fc")) {
79 port->disc_addr.adrfam = NVMF_ADDR_FAMILY_FC;
a07b4970
CH
80 } else {
81 pr_err("Invalid value '%s' for adrfam\n", page);
82 return -EINVAL;
83 }
84
85 return count;
86}
87
88CONFIGFS_ATTR(nvmet_, addr_adrfam);
89
90static ssize_t nvmet_addr_portid_show(struct config_item *item,
91 char *page)
92{
93 struct nvmet_port *port = to_nvmet_port(item);
94
95 return snprintf(page, PAGE_SIZE, "%d\n",
96 le16_to_cpu(port->disc_addr.portid));
97}
98
99static ssize_t nvmet_addr_portid_store(struct config_item *item,
100 const char *page, size_t count)
101{
102 struct nvmet_port *port = to_nvmet_port(item);
103 u16 portid = 0;
104
105 if (kstrtou16(page, 0, &portid)) {
106 pr_err("Invalid value '%s' for portid\n", page);
107 return -EINVAL;
108 }
109
110 if (port->enabled) {
111 pr_err("Cannot modify address while enabled\n");
112 pr_err("Disable the address before modifying\n");
113 return -EACCES;
114 }
115 port->disc_addr.portid = cpu_to_le16(portid);
116 return count;
117}
118
119CONFIGFS_ATTR(nvmet_, addr_portid);
120
121static ssize_t nvmet_addr_traddr_show(struct config_item *item,
122 char *page)
123{
124 struct nvmet_port *port = to_nvmet_port(item);
125
126 return snprintf(page, PAGE_SIZE, "%s\n",
127 port->disc_addr.traddr);
128}
129
130static ssize_t nvmet_addr_traddr_store(struct config_item *item,
131 const char *page, size_t count)
132{
133 struct nvmet_port *port = to_nvmet_port(item);
134
135 if (count > NVMF_TRADDR_SIZE) {
136 pr_err("Invalid value '%s' for traddr\n", page);
137 return -EINVAL;
138 }
139
140 if (port->enabled) {
141 pr_err("Cannot modify address while enabled\n");
142 pr_err("Disable the address before modifying\n");
143 return -EACCES;
144 }
9ba2a5cb
SG
145
146 if (sscanf(page, "%s\n", port->disc_addr.traddr) != 1)
147 return -EINVAL;
148 return count;
a07b4970
CH
149}
150
151CONFIGFS_ATTR(nvmet_, addr_traddr);
152
153static ssize_t nvmet_addr_treq_show(struct config_item *item,
154 char *page)
155{
0445e1b5
SG
156 switch (to_nvmet_port(item)->disc_addr.treq &
157 NVME_TREQ_SECURE_CHANNEL_MASK) {
a07b4970
CH
158 case NVMF_TREQ_NOT_SPECIFIED:
159 return sprintf(page, "not specified\n");
160 case NVMF_TREQ_REQUIRED:
161 return sprintf(page, "required\n");
162 case NVMF_TREQ_NOT_REQUIRED:
163 return sprintf(page, "not required\n");
164 default:
165 return sprintf(page, "\n");
166 }
167}
168
169static ssize_t nvmet_addr_treq_store(struct config_item *item,
170 const char *page, size_t count)
171{
172 struct nvmet_port *port = to_nvmet_port(item);
0445e1b5 173 u8 treq = port->disc_addr.treq & ~NVME_TREQ_SECURE_CHANNEL_MASK;
a07b4970
CH
174
175 if (port->enabled) {
176 pr_err("Cannot modify address while enabled\n");
177 pr_err("Disable the address before modifying\n");
178 return -EACCES;
179 }
180
181 if (sysfs_streq(page, "not specified")) {
0445e1b5 182 treq |= NVMF_TREQ_NOT_SPECIFIED;
a07b4970 183 } else if (sysfs_streq(page, "required")) {
0445e1b5 184 treq |= NVMF_TREQ_REQUIRED;
a07b4970 185 } else if (sysfs_streq(page, "not required")) {
0445e1b5 186 treq |= NVMF_TREQ_NOT_REQUIRED;
a07b4970
CH
187 } else {
188 pr_err("Invalid value '%s' for treq\n", page);
189 return -EINVAL;
190 }
0445e1b5 191 port->disc_addr.treq = treq;
a07b4970
CH
192
193 return count;
194}
195
196CONFIGFS_ATTR(nvmet_, addr_treq);
197
198static ssize_t nvmet_addr_trsvcid_show(struct config_item *item,
199 char *page)
200{
201 struct nvmet_port *port = to_nvmet_port(item);
202
203 return snprintf(page, PAGE_SIZE, "%s\n",
204 port->disc_addr.trsvcid);
205}
206
207static ssize_t nvmet_addr_trsvcid_store(struct config_item *item,
208 const char *page, size_t count)
209{
210 struct nvmet_port *port = to_nvmet_port(item);
211
212 if (count > NVMF_TRSVCID_SIZE) {
213 pr_err("Invalid value '%s' for trsvcid\n", page);
214 return -EINVAL;
215 }
216 if (port->enabled) {
217 pr_err("Cannot modify address while enabled\n");
218 pr_err("Disable the address before modifying\n");
219 return -EACCES;
220 }
9ba2a5cb
SG
221
222 if (sscanf(page, "%s\n", port->disc_addr.trsvcid) != 1)
223 return -EINVAL;
224 return count;
a07b4970
CH
225}
226
227CONFIGFS_ATTR(nvmet_, addr_trsvcid);
228
0d5ee2b2
SW
229static ssize_t nvmet_param_inline_data_size_show(struct config_item *item,
230 char *page)
231{
232 struct nvmet_port *port = to_nvmet_port(item);
233
234 return snprintf(page, PAGE_SIZE, "%d\n", port->inline_data_size);
235}
236
237static ssize_t nvmet_param_inline_data_size_store(struct config_item *item,
238 const char *page, size_t count)
239{
240 struct nvmet_port *port = to_nvmet_port(item);
241 int ret;
242
243 if (port->enabled) {
244 pr_err("Cannot modify inline_data_size while port enabled\n");
245 pr_err("Disable the port before modifying\n");
246 return -EACCES;
247 }
248 ret = kstrtoint(page, 0, &port->inline_data_size);
249 if (ret) {
250 pr_err("Invalid value '%s' for inline_data_size\n", page);
251 return -EINVAL;
252 }
253 return count;
254}
255
256CONFIGFS_ATTR(nvmet_, param_inline_data_size);
257
a07b4970
CH
258static ssize_t nvmet_addr_trtype_show(struct config_item *item,
259 char *page)
260{
a5d18612
CH
261 struct nvmet_port *port = to_nvmet_port(item);
262 int i;
263
264 for (i = 0; i < ARRAY_SIZE(nvmet_transport_names); i++) {
265 if (port->disc_addr.trtype != nvmet_transport_names[i].type)
266 continue;
267 return sprintf(page, "%s\n", nvmet_transport_names[i].name);
a07b4970 268 }
a5d18612
CH
269
270 return sprintf(page, "\n");
a07b4970
CH
271}
272
273static void nvmet_port_init_tsas_rdma(struct nvmet_port *port)
274{
a07b4970
CH
275 port->disc_addr.tsas.rdma.qptype = NVMF_RDMA_QPTYPE_CONNECTED;
276 port->disc_addr.tsas.rdma.prtype = NVMF_RDMA_PRTYPE_NOT_SPECIFIED;
277 port->disc_addr.tsas.rdma.cms = NVMF_RDMA_CMS_RDMA_CM;
278}
279
a07b4970
CH
280static ssize_t nvmet_addr_trtype_store(struct config_item *item,
281 const char *page, size_t count)
282{
283 struct nvmet_port *port = to_nvmet_port(item);
a5d18612 284 int i;
a07b4970
CH
285
286 if (port->enabled) {
287 pr_err("Cannot modify address while enabled\n");
288 pr_err("Disable the address before modifying\n");
289 return -EACCES;
290 }
291
a5d18612
CH
292 for (i = 0; i < ARRAY_SIZE(nvmet_transport_names); i++) {
293 if (sysfs_streq(page, nvmet_transport_names[i].name))
294 goto found;
a07b4970
CH
295 }
296
a5d18612
CH
297 pr_err("Invalid value '%s' for trtype\n", page);
298 return -EINVAL;
299found:
300 memset(&port->disc_addr.tsas, 0, NVMF_TSAS_SIZE);
301 port->disc_addr.trtype = nvmet_transport_names[i].type;
302 if (port->disc_addr.trtype == NVMF_TRTYPE_RDMA)
303 nvmet_port_init_tsas_rdma(port);
a07b4970
CH
304 return count;
305}
306
307CONFIGFS_ATTR(nvmet_, addr_trtype);
308
309/*
310 * Namespace structures & file operation functions below
311 */
312static ssize_t nvmet_ns_device_path_show(struct config_item *item, char *page)
313{
314 return sprintf(page, "%s\n", to_nvmet_ns(item)->device_path);
315}
316
317static ssize_t nvmet_ns_device_path_store(struct config_item *item,
318 const char *page, size_t count)
319{
320 struct nvmet_ns *ns = to_nvmet_ns(item);
321 struct nvmet_subsys *subsys = ns->subsys;
5613d312 322 size_t len;
a07b4970
CH
323 int ret;
324
325 mutex_lock(&subsys->lock);
326 ret = -EBUSY;
e4fcf07c 327 if (ns->enabled)
a07b4970
CH
328 goto out_unlock;
329
5613d312
HR
330 ret = -EINVAL;
331 len = strcspn(page, "\n");
332 if (!len)
333 goto out_unlock;
a07b4970 334
5613d312 335 kfree(ns->device_path);
a07b4970 336 ret = -ENOMEM;
5613d312 337 ns->device_path = kstrndup(page, len, GFP_KERNEL);
a07b4970
CH
338 if (!ns->device_path)
339 goto out_unlock;
340
341 mutex_unlock(&subsys->lock);
342 return count;
343
344out_unlock:
345 mutex_unlock(&subsys->lock);
346 return ret;
347}
348
349CONFIGFS_ATTR(nvmet_ns_, device_path);
350
c6925093
LG
351#ifdef CONFIG_PCI_P2PDMA
352static ssize_t nvmet_ns_p2pmem_show(struct config_item *item, char *page)
353{
354 struct nvmet_ns *ns = to_nvmet_ns(item);
355
356 return pci_p2pdma_enable_show(page, ns->p2p_dev, ns->use_p2pmem);
357}
358
359static ssize_t nvmet_ns_p2pmem_store(struct config_item *item,
360 const char *page, size_t count)
361{
362 struct nvmet_ns *ns = to_nvmet_ns(item);
363 struct pci_dev *p2p_dev = NULL;
364 bool use_p2pmem;
365 int ret = count;
366 int error;
367
368 mutex_lock(&ns->subsys->lock);
369 if (ns->enabled) {
370 ret = -EBUSY;
371 goto out_unlock;
372 }
373
374 error = pci_p2pdma_enable_store(page, &p2p_dev, &use_p2pmem);
375 if (error) {
376 ret = error;
377 goto out_unlock;
378 }
379
380 ns->use_p2pmem = use_p2pmem;
381 pci_dev_put(ns->p2p_dev);
382 ns->p2p_dev = p2p_dev;
383
384out_unlock:
385 mutex_unlock(&ns->subsys->lock);
386
387 return ret;
388}
389
390CONFIGFS_ATTR(nvmet_ns_, p2pmem);
391#endif /* CONFIG_PCI_P2PDMA */
392
430c7bef
JT
393static ssize_t nvmet_ns_device_uuid_show(struct config_item *item, char *page)
394{
395 return sprintf(page, "%pUb\n", &to_nvmet_ns(item)->uuid);
396}
397
398static ssize_t nvmet_ns_device_uuid_store(struct config_item *item,
399 const char *page, size_t count)
400{
401 struct nvmet_ns *ns = to_nvmet_ns(item);
402 struct nvmet_subsys *subsys = ns->subsys;
403 int ret = 0;
404
405
406 mutex_lock(&subsys->lock);
407 if (ns->enabled) {
408 ret = -EBUSY;
409 goto out_unlock;
410 }
411
412
413 if (uuid_parse(page, &ns->uuid))
414 ret = -EINVAL;
415
416out_unlock:
417 mutex_unlock(&subsys->lock);
418 return ret ? ret : count;
419}
420
f871749a
MG
421CONFIGFS_ATTR(nvmet_ns_, device_uuid);
422
a07b4970
CH
423static ssize_t nvmet_ns_device_nguid_show(struct config_item *item, char *page)
424{
425 return sprintf(page, "%pUb\n", &to_nvmet_ns(item)->nguid);
426}
427
428static ssize_t nvmet_ns_device_nguid_store(struct config_item *item,
429 const char *page, size_t count)
430{
431 struct nvmet_ns *ns = to_nvmet_ns(item);
432 struct nvmet_subsys *subsys = ns->subsys;
433 u8 nguid[16];
434 const char *p = page;
435 int i;
436 int ret = 0;
437
438 mutex_lock(&subsys->lock);
e4fcf07c 439 if (ns->enabled) {
a07b4970
CH
440 ret = -EBUSY;
441 goto out_unlock;
442 }
443
444 for (i = 0; i < 16; i++) {
445 if (p + 2 > page + count) {
446 ret = -EINVAL;
447 goto out_unlock;
448 }
449 if (!isxdigit(p[0]) || !isxdigit(p[1])) {
450 ret = -EINVAL;
451 goto out_unlock;
452 }
453
454 nguid[i] = (hex_to_bin(p[0]) << 4) | hex_to_bin(p[1]);
455 p += 2;
456
457 if (*p == '-' || *p == ':')
458 p++;
459 }
460
461 memcpy(&ns->nguid, nguid, sizeof(nguid));
462out_unlock:
463 mutex_unlock(&subsys->lock);
464 return ret ? ret : count;
465}
466
467CONFIGFS_ATTR(nvmet_ns_, device_nguid);
468
62ac0d32
CH
469static ssize_t nvmet_ns_ana_grpid_show(struct config_item *item, char *page)
470{
471 return sprintf(page, "%u\n", to_nvmet_ns(item)->anagrpid);
472}
473
474static ssize_t nvmet_ns_ana_grpid_store(struct config_item *item,
475 const char *page, size_t count)
476{
477 struct nvmet_ns *ns = to_nvmet_ns(item);
478 u32 oldgrpid, newgrpid;
479 int ret;
480
481 ret = kstrtou32(page, 0, &newgrpid);
482 if (ret)
483 return ret;
484
485 if (newgrpid < 1 || newgrpid > NVMET_MAX_ANAGRPS)
486 return -EINVAL;
487
488 down_write(&nvmet_ana_sem);
489 oldgrpid = ns->anagrpid;
490 nvmet_ana_group_enabled[newgrpid]++;
491 ns->anagrpid = newgrpid;
492 nvmet_ana_group_enabled[oldgrpid]--;
493 nvmet_ana_chgcnt++;
494 up_write(&nvmet_ana_sem);
495
496 nvmet_send_ana_event(ns->subsys, NULL);
497 return count;
498}
499
500CONFIGFS_ATTR(nvmet_ns_, ana_grpid);
501
a07b4970
CH
502static ssize_t nvmet_ns_enable_show(struct config_item *item, char *page)
503{
e4fcf07c 504 return sprintf(page, "%d\n", to_nvmet_ns(item)->enabled);
a07b4970
CH
505}
506
507static ssize_t nvmet_ns_enable_store(struct config_item *item,
508 const char *page, size_t count)
509{
510 struct nvmet_ns *ns = to_nvmet_ns(item);
511 bool enable;
512 int ret = 0;
513
514 if (strtobool(page, &enable))
515 return -EINVAL;
516
517 if (enable)
518 ret = nvmet_ns_enable(ns);
519 else
520 nvmet_ns_disable(ns);
521
522 return ret ? ret : count;
523}
524
525CONFIGFS_ATTR(nvmet_ns_, enable);
526
55eb942e
CK
527static ssize_t nvmet_ns_buffered_io_show(struct config_item *item, char *page)
528{
529 return sprintf(page, "%d\n", to_nvmet_ns(item)->buffered_io);
530}
531
532static ssize_t nvmet_ns_buffered_io_store(struct config_item *item,
533 const char *page, size_t count)
534{
535 struct nvmet_ns *ns = to_nvmet_ns(item);
536 bool val;
537
538 if (strtobool(page, &val))
539 return -EINVAL;
540
541 mutex_lock(&ns->subsys->lock);
542 if (ns->enabled) {
543 pr_err("disable ns before setting buffered_io value.\n");
544 mutex_unlock(&ns->subsys->lock);
545 return -EINVAL;
546 }
547
548 ns->buffered_io = val;
549 mutex_unlock(&ns->subsys->lock);
550 return count;
551}
552
553CONFIGFS_ATTR(nvmet_ns_, buffered_io);
554
a07b4970
CH
555static struct configfs_attribute *nvmet_ns_attrs[] = {
556 &nvmet_ns_attr_device_path,
557 &nvmet_ns_attr_device_nguid,
430c7bef 558 &nvmet_ns_attr_device_uuid,
62ac0d32 559 &nvmet_ns_attr_ana_grpid,
a07b4970 560 &nvmet_ns_attr_enable,
55eb942e 561 &nvmet_ns_attr_buffered_io,
c6925093
LG
562#ifdef CONFIG_PCI_P2PDMA
563 &nvmet_ns_attr_p2pmem,
564#endif
a07b4970
CH
565 NULL,
566};
567
568static void nvmet_ns_release(struct config_item *item)
569{
570 struct nvmet_ns *ns = to_nvmet_ns(item);
571
572 nvmet_ns_free(ns);
573}
574
575static struct configfs_item_operations nvmet_ns_item_ops = {
576 .release = nvmet_ns_release,
577};
578
66603a31 579static const struct config_item_type nvmet_ns_type = {
a07b4970
CH
580 .ct_item_ops = &nvmet_ns_item_ops,
581 .ct_attrs = nvmet_ns_attrs,
582 .ct_owner = THIS_MODULE,
583};
584
585static struct config_group *nvmet_ns_make(struct config_group *group,
586 const char *name)
587{
588 struct nvmet_subsys *subsys = namespaces_to_subsys(&group->cg_item);
589 struct nvmet_ns *ns;
590 int ret;
591 u32 nsid;
592
593 ret = kstrtou32(name, 0, &nsid);
594 if (ret)
595 goto out;
596
597 ret = -EINVAL;
1645d503 598 if (nsid == 0 || nsid == NVME_NSID_ALL)
a07b4970
CH
599 goto out;
600
601 ret = -ENOMEM;
602 ns = nvmet_ns_alloc(subsys, nsid);
603 if (!ns)
604 goto out;
605 config_group_init_type_name(&ns->group, name, &nvmet_ns_type);
606
607 pr_info("adding nsid %d to subsystem %s\n", nsid, subsys->subsysnqn);
608
609 return &ns->group;
610out:
611 return ERR_PTR(ret);
612}
613
614static struct configfs_group_operations nvmet_namespaces_group_ops = {
615 .make_group = nvmet_ns_make,
616};
617
66603a31 618static const struct config_item_type nvmet_namespaces_type = {
a07b4970
CH
619 .ct_group_ops = &nvmet_namespaces_group_ops,
620 .ct_owner = THIS_MODULE,
621};
622
623static int nvmet_port_subsys_allow_link(struct config_item *parent,
624 struct config_item *target)
625{
626 struct nvmet_port *port = to_nvmet_port(parent->ci_parent);
627 struct nvmet_subsys *subsys;
628 struct nvmet_subsys_link *link, *p;
629 int ret;
630
631 if (target->ci_type != &nvmet_subsys_type) {
632 pr_err("can only link subsystems into the subsystems dir.!\n");
633 return -EINVAL;
634 }
635 subsys = to_subsys(target);
636 link = kmalloc(sizeof(*link), GFP_KERNEL);
637 if (!link)
638 return -ENOMEM;
639 link->subsys = subsys;
640
641 down_write(&nvmet_config_sem);
642 ret = -EEXIST;
643 list_for_each_entry(p, &port->subsystems, entry) {
644 if (p->subsys == subsys)
645 goto out_free_link;
646 }
647
648 if (list_empty(&port->subsystems)) {
649 ret = nvmet_enable_port(port);
650 if (ret)
651 goto out_free_link;
652 }
653
654 list_add_tail(&link->entry, &port->subsystems);
b662a078
JS
655 nvmet_port_disc_changed(port, subsys);
656
a07b4970
CH
657 up_write(&nvmet_config_sem);
658 return 0;
659
660out_free_link:
661 up_write(&nvmet_config_sem);
662 kfree(link);
663 return ret;
664}
665
e16769d4 666static void nvmet_port_subsys_drop_link(struct config_item *parent,
a07b4970
CH
667 struct config_item *target)
668{
669 struct nvmet_port *port = to_nvmet_port(parent->ci_parent);
670 struct nvmet_subsys *subsys = to_subsys(target);
671 struct nvmet_subsys_link *p;
672
673 down_write(&nvmet_config_sem);
674 list_for_each_entry(p, &port->subsystems, entry) {
675 if (p->subsys == subsys)
676 goto found;
677 }
678 up_write(&nvmet_config_sem);
e16769d4 679 return;
a07b4970
CH
680
681found:
682 list_del(&p->entry);
b662a078
JS
683 nvmet_port_disc_changed(port, subsys);
684
a07b4970
CH
685 if (list_empty(&port->subsystems))
686 nvmet_disable_port(port);
687 up_write(&nvmet_config_sem);
688 kfree(p);
a07b4970
CH
689}
690
691static struct configfs_item_operations nvmet_port_subsys_item_ops = {
692 .allow_link = nvmet_port_subsys_allow_link,
693 .drop_link = nvmet_port_subsys_drop_link,
694};
695
66603a31 696static const struct config_item_type nvmet_port_subsys_type = {
a07b4970
CH
697 .ct_item_ops = &nvmet_port_subsys_item_ops,
698 .ct_owner = THIS_MODULE,
699};
700
701static int nvmet_allowed_hosts_allow_link(struct config_item *parent,
702 struct config_item *target)
703{
704 struct nvmet_subsys *subsys = to_subsys(parent->ci_parent);
705 struct nvmet_host *host;
706 struct nvmet_host_link *link, *p;
707 int ret;
708
709 if (target->ci_type != &nvmet_host_type) {
710 pr_err("can only link hosts into the allowed_hosts directory!\n");
711 return -EINVAL;
712 }
713
714 host = to_host(target);
715 link = kmalloc(sizeof(*link), GFP_KERNEL);
716 if (!link)
717 return -ENOMEM;
718 link->host = host;
719
720 down_write(&nvmet_config_sem);
721 ret = -EINVAL;
722 if (subsys->allow_any_host) {
723 pr_err("can't add hosts when allow_any_host is set!\n");
724 goto out_free_link;
725 }
726
727 ret = -EEXIST;
728 list_for_each_entry(p, &subsys->hosts, entry) {
729 if (!strcmp(nvmet_host_name(p->host), nvmet_host_name(host)))
730 goto out_free_link;
731 }
732 list_add_tail(&link->entry, &subsys->hosts);
b662a078
JS
733 nvmet_subsys_disc_changed(subsys, host);
734
a07b4970
CH
735 up_write(&nvmet_config_sem);
736 return 0;
737out_free_link:
738 up_write(&nvmet_config_sem);
739 kfree(link);
740 return ret;
741}
742
e16769d4 743static void nvmet_allowed_hosts_drop_link(struct config_item *parent,
a07b4970
CH
744 struct config_item *target)
745{
746 struct nvmet_subsys *subsys = to_subsys(parent->ci_parent);
747 struct nvmet_host *host = to_host(target);
748 struct nvmet_host_link *p;
749
750 down_write(&nvmet_config_sem);
751 list_for_each_entry(p, &subsys->hosts, entry) {
752 if (!strcmp(nvmet_host_name(p->host), nvmet_host_name(host)))
753 goto found;
754 }
755 up_write(&nvmet_config_sem);
e16769d4 756 return;
a07b4970
CH
757
758found:
759 list_del(&p->entry);
b662a078
JS
760 nvmet_subsys_disc_changed(subsys, host);
761
a07b4970
CH
762 up_write(&nvmet_config_sem);
763 kfree(p);
a07b4970
CH
764}
765
766static struct configfs_item_operations nvmet_allowed_hosts_item_ops = {
767 .allow_link = nvmet_allowed_hosts_allow_link,
768 .drop_link = nvmet_allowed_hosts_drop_link,
769};
770
66603a31 771static const struct config_item_type nvmet_allowed_hosts_type = {
a07b4970
CH
772 .ct_item_ops = &nvmet_allowed_hosts_item_ops,
773 .ct_owner = THIS_MODULE,
774};
775
776static ssize_t nvmet_subsys_attr_allow_any_host_show(struct config_item *item,
777 char *page)
778{
779 return snprintf(page, PAGE_SIZE, "%d\n",
780 to_subsys(item)->allow_any_host);
781}
782
783static ssize_t nvmet_subsys_attr_allow_any_host_store(struct config_item *item,
784 const char *page, size_t count)
785{
786 struct nvmet_subsys *subsys = to_subsys(item);
787 bool allow_any_host;
788 int ret = 0;
789
790 if (strtobool(page, &allow_any_host))
791 return -EINVAL;
792
793 down_write(&nvmet_config_sem);
794 if (allow_any_host && !list_empty(&subsys->hosts)) {
795 pr_err("Can't set allow_any_host when explicit hosts are set!\n");
796 ret = -EINVAL;
797 goto out_unlock;
798 }
799
b662a078
JS
800 if (subsys->allow_any_host != allow_any_host) {
801 subsys->allow_any_host = allow_any_host;
802 nvmet_subsys_disc_changed(subsys, NULL);
803 }
804
a07b4970
CH
805out_unlock:
806 up_write(&nvmet_config_sem);
807 return ret ? ret : count;
808}
809
810CONFIGFS_ATTR(nvmet_subsys_, attr_allow_any_host);
811
41528f80 812static ssize_t nvmet_subsys_attr_version_show(struct config_item *item,
c61d788b
JT
813 char *page)
814{
815 struct nvmet_subsys *subsys = to_subsys(item);
816
817 if (NVME_TERTIARY(subsys->ver))
818 return snprintf(page, PAGE_SIZE, "%d.%d.%d\n",
819 (int)NVME_MAJOR(subsys->ver),
820 (int)NVME_MINOR(subsys->ver),
821 (int)NVME_TERTIARY(subsys->ver));
822 else
823 return snprintf(page, PAGE_SIZE, "%d.%d\n",
824 (int)NVME_MAJOR(subsys->ver),
825 (int)NVME_MINOR(subsys->ver));
826}
827
41528f80 828static ssize_t nvmet_subsys_attr_version_store(struct config_item *item,
c61d788b
JT
829 const char *page, size_t count)
830{
831 struct nvmet_subsys *subsys = to_subsys(item);
832 int major, minor, tertiary = 0;
833 int ret;
834
835
836 ret = sscanf(page, "%d.%d.%d\n", &major, &minor, &tertiary);
837 if (ret != 2 && ret != 3)
838 return -EINVAL;
839
840 down_write(&nvmet_config_sem);
841 subsys->ver = NVME_VS(major, minor, tertiary);
842 up_write(&nvmet_config_sem);
843
844 return count;
845}
41528f80 846CONFIGFS_ATTR(nvmet_subsys_, attr_version);
c61d788b 847
fcbc5459
JT
848static ssize_t nvmet_subsys_attr_serial_show(struct config_item *item,
849 char *page)
850{
851 struct nvmet_subsys *subsys = to_subsys(item);
852
853 return snprintf(page, PAGE_SIZE, "%llx\n", subsys->serial);
854}
855
856static ssize_t nvmet_subsys_attr_serial_store(struct config_item *item,
857 const char *page, size_t count)
858{
859 struct nvmet_subsys *subsys = to_subsys(item);
860
861 down_write(&nvmet_config_sem);
862 sscanf(page, "%llx\n", &subsys->serial);
863 up_write(&nvmet_config_sem);
864
865 return count;
866}
867CONFIGFS_ATTR(nvmet_subsys_, attr_serial);
868
a07b4970
CH
869static struct configfs_attribute *nvmet_subsys_attrs[] = {
870 &nvmet_subsys_attr_attr_allow_any_host,
41528f80 871 &nvmet_subsys_attr_attr_version,
fcbc5459 872 &nvmet_subsys_attr_attr_serial,
a07b4970
CH
873 NULL,
874};
875
876/*
877 * Subsystem structures & folder operation functions below
878 */
879static void nvmet_subsys_release(struct config_item *item)
880{
881 struct nvmet_subsys *subsys = to_subsys(item);
882
344770b0 883 nvmet_subsys_del_ctrls(subsys);
a07b4970
CH
884 nvmet_subsys_put(subsys);
885}
886
887static struct configfs_item_operations nvmet_subsys_item_ops = {
888 .release = nvmet_subsys_release,
889};
890
66603a31 891static const struct config_item_type nvmet_subsys_type = {
a07b4970
CH
892 .ct_item_ops = &nvmet_subsys_item_ops,
893 .ct_attrs = nvmet_subsys_attrs,
894 .ct_owner = THIS_MODULE,
895};
896
897static struct config_group *nvmet_subsys_make(struct config_group *group,
898 const char *name)
899{
900 struct nvmet_subsys *subsys;
901
902 if (sysfs_streq(name, NVME_DISC_SUBSYS_NAME)) {
903 pr_err("can't create discovery subsystem through configfs\n");
904 return ERR_PTR(-EINVAL);
905 }
906
907 subsys = nvmet_subsys_alloc(name, NVME_NQN_NVME);
908 if (!subsys)
909 return ERR_PTR(-ENOMEM);
910
911 config_group_init_type_name(&subsys->group, name, &nvmet_subsys_type);
912
913 config_group_init_type_name(&subsys->namespaces_group,
914 "namespaces", &nvmet_namespaces_type);
915 configfs_add_default_group(&subsys->namespaces_group, &subsys->group);
916
917 config_group_init_type_name(&subsys->allowed_hosts_group,
918 "allowed_hosts", &nvmet_allowed_hosts_type);
919 configfs_add_default_group(&subsys->allowed_hosts_group,
920 &subsys->group);
921
922 return &subsys->group;
923}
924
925static struct configfs_group_operations nvmet_subsystems_group_ops = {
926 .make_group = nvmet_subsys_make,
927};
928
66603a31 929static const struct config_item_type nvmet_subsystems_type = {
a07b4970
CH
930 .ct_group_ops = &nvmet_subsystems_group_ops,
931 .ct_owner = THIS_MODULE,
932};
933
934static ssize_t nvmet_referral_enable_show(struct config_item *item,
935 char *page)
936{
937 return snprintf(page, PAGE_SIZE, "%d\n", to_nvmet_port(item)->enabled);
938}
939
940static ssize_t nvmet_referral_enable_store(struct config_item *item,
941 const char *page, size_t count)
942{
943 struct nvmet_port *parent = to_nvmet_port(item->ci_parent->ci_parent);
944 struct nvmet_port *port = to_nvmet_port(item);
945 bool enable;
946
947 if (strtobool(page, &enable))
948 goto inval;
949
950 if (enable)
951 nvmet_referral_enable(parent, port);
952 else
b662a078 953 nvmet_referral_disable(parent, port);
a07b4970
CH
954
955 return count;
956inval:
957 pr_err("Invalid value '%s' for enable\n", page);
958 return -EINVAL;
959}
960
961CONFIGFS_ATTR(nvmet_referral_, enable);
962
963/*
964 * Discovery Service subsystem definitions
965 */
966static struct configfs_attribute *nvmet_referral_attrs[] = {
967 &nvmet_attr_addr_adrfam,
968 &nvmet_attr_addr_portid,
969 &nvmet_attr_addr_treq,
970 &nvmet_attr_addr_traddr,
971 &nvmet_attr_addr_trsvcid,
972 &nvmet_attr_addr_trtype,
973 &nvmet_referral_attr_enable,
974 NULL,
975};
976
977static void nvmet_referral_release(struct config_item *item)
978{
b662a078 979 struct nvmet_port *parent = to_nvmet_port(item->ci_parent->ci_parent);
a07b4970
CH
980 struct nvmet_port *port = to_nvmet_port(item);
981
b662a078 982 nvmet_referral_disable(parent, port);
a07b4970
CH
983 kfree(port);
984}
985
986static struct configfs_item_operations nvmet_referral_item_ops = {
987 .release = nvmet_referral_release,
988};
989
66603a31 990static const struct config_item_type nvmet_referral_type = {
a07b4970
CH
991 .ct_owner = THIS_MODULE,
992 .ct_attrs = nvmet_referral_attrs,
993 .ct_item_ops = &nvmet_referral_item_ops,
994};
995
996static struct config_group *nvmet_referral_make(
997 struct config_group *group, const char *name)
998{
999 struct nvmet_port *port;
1000
1001 port = kzalloc(sizeof(*port), GFP_KERNEL);
1002 if (!port)
f98d9ca1 1003 return ERR_PTR(-ENOMEM);
a07b4970
CH
1004
1005 INIT_LIST_HEAD(&port->entry);
1006 config_group_init_type_name(&port->group, name, &nvmet_referral_type);
1007
1008 return &port->group;
1009}
1010
1011static struct configfs_group_operations nvmet_referral_group_ops = {
1012 .make_group = nvmet_referral_make,
1013};
1014
66603a31 1015static const struct config_item_type nvmet_referrals_type = {
a07b4970
CH
1016 .ct_owner = THIS_MODULE,
1017 .ct_group_ops = &nvmet_referral_group_ops,
1018};
1019
62ac0d32
CH
1020static struct {
1021 enum nvme_ana_state state;
1022 const char *name;
1023} nvmet_ana_state_names[] = {
1024 { NVME_ANA_OPTIMIZED, "optimized" },
1025 { NVME_ANA_NONOPTIMIZED, "non-optimized" },
1026 { NVME_ANA_INACCESSIBLE, "inaccessible" },
1027 { NVME_ANA_PERSISTENT_LOSS, "persistent-loss" },
1028 { NVME_ANA_CHANGE, "change" },
1029};
1030
1031static ssize_t nvmet_ana_group_ana_state_show(struct config_item *item,
1032 char *page)
1033{
1034 struct nvmet_ana_group *grp = to_ana_group(item);
1035 enum nvme_ana_state state = grp->port->ana_state[grp->grpid];
1036 int i;
1037
1038 for (i = 0; i < ARRAY_SIZE(nvmet_ana_state_names); i++) {
1039 if (state != nvmet_ana_state_names[i].state)
1040 continue;
1041 return sprintf(page, "%s\n", nvmet_ana_state_names[i].name);
1042 }
1043
1044 return sprintf(page, "\n");
1045}
1046
1047static ssize_t nvmet_ana_group_ana_state_store(struct config_item *item,
1048 const char *page, size_t count)
1049{
1050 struct nvmet_ana_group *grp = to_ana_group(item);
1051 int i;
1052
1053 for (i = 0; i < ARRAY_SIZE(nvmet_ana_state_names); i++) {
1054 if (sysfs_streq(page, nvmet_ana_state_names[i].name))
1055 goto found;
1056 }
1057
1058 pr_err("Invalid value '%s' for ana_state\n", page);
1059 return -EINVAL;
1060
1061found:
1062 down_write(&nvmet_ana_sem);
1063 grp->port->ana_state[grp->grpid] = nvmet_ana_state_names[i].state;
1064 nvmet_ana_chgcnt++;
1065 up_write(&nvmet_ana_sem);
1066
1067 nvmet_port_send_ana_event(grp->port);
1068 return count;
1069}
1070
1071CONFIGFS_ATTR(nvmet_ana_group_, ana_state);
1072
1073static struct configfs_attribute *nvmet_ana_group_attrs[] = {
1074 &nvmet_ana_group_attr_ana_state,
1075 NULL,
1076};
1077
1078static void nvmet_ana_group_release(struct config_item *item)
1079{
1080 struct nvmet_ana_group *grp = to_ana_group(item);
1081
1082 if (grp == &grp->port->ana_default_group)
1083 return;
1084
1085 down_write(&nvmet_ana_sem);
1086 grp->port->ana_state[grp->grpid] = NVME_ANA_INACCESSIBLE;
1087 nvmet_ana_group_enabled[grp->grpid]--;
1088 up_write(&nvmet_ana_sem);
1089
1090 nvmet_port_send_ana_event(grp->port);
1091 kfree(grp);
1092}
1093
1094static struct configfs_item_operations nvmet_ana_group_item_ops = {
1095 .release = nvmet_ana_group_release,
1096};
1097
1098static const struct config_item_type nvmet_ana_group_type = {
1099 .ct_item_ops = &nvmet_ana_group_item_ops,
1100 .ct_attrs = nvmet_ana_group_attrs,
1101 .ct_owner = THIS_MODULE,
1102};
1103
1104static struct config_group *nvmet_ana_groups_make_group(
1105 struct config_group *group, const char *name)
1106{
1107 struct nvmet_port *port = ana_groups_to_port(&group->cg_item);
1108 struct nvmet_ana_group *grp;
1109 u32 grpid;
1110 int ret;
1111
1112 ret = kstrtou32(name, 0, &grpid);
1113 if (ret)
1114 goto out;
1115
1116 ret = -EINVAL;
1117 if (grpid <= 1 || grpid > NVMET_MAX_ANAGRPS)
1118 goto out;
1119
1120 ret = -ENOMEM;
1121 grp = kzalloc(sizeof(*grp), GFP_KERNEL);
1122 if (!grp)
1123 goto out;
1124 grp->port = port;
1125 grp->grpid = grpid;
1126
1127 down_write(&nvmet_ana_sem);
1128 nvmet_ana_group_enabled[grpid]++;
1129 up_write(&nvmet_ana_sem);
1130
1131 nvmet_port_send_ana_event(grp->port);
1132
1133 config_group_init_type_name(&grp->group, name, &nvmet_ana_group_type);
1134 return &grp->group;
1135out:
1136 return ERR_PTR(ret);
1137}
1138
1139static struct configfs_group_operations nvmet_ana_groups_group_ops = {
1140 .make_group = nvmet_ana_groups_make_group,
1141};
1142
1143static const struct config_item_type nvmet_ana_groups_type = {
1144 .ct_group_ops = &nvmet_ana_groups_group_ops,
1145 .ct_owner = THIS_MODULE,
1146};
1147
a07b4970
CH
1148/*
1149 * Ports definitions.
1150 */
1151static void nvmet_port_release(struct config_item *item)
1152{
1153 struct nvmet_port *port = to_nvmet_port(item);
1154
b662a078
JS
1155 list_del(&port->global_entry);
1156
72efd25d 1157 kfree(port->ana_state);
a07b4970
CH
1158 kfree(port);
1159}
1160
1161static struct configfs_attribute *nvmet_port_attrs[] = {
1162 &nvmet_attr_addr_adrfam,
1163 &nvmet_attr_addr_treq,
1164 &nvmet_attr_addr_traddr,
1165 &nvmet_attr_addr_trsvcid,
1166 &nvmet_attr_addr_trtype,
0d5ee2b2 1167 &nvmet_attr_param_inline_data_size,
a07b4970
CH
1168 NULL,
1169};
1170
1171static struct configfs_item_operations nvmet_port_item_ops = {
1172 .release = nvmet_port_release,
1173};
1174
66603a31 1175static const struct config_item_type nvmet_port_type = {
a07b4970
CH
1176 .ct_attrs = nvmet_port_attrs,
1177 .ct_item_ops = &nvmet_port_item_ops,
1178 .ct_owner = THIS_MODULE,
1179};
1180
1181static struct config_group *nvmet_ports_make(struct config_group *group,
1182 const char *name)
1183{
1184 struct nvmet_port *port;
1185 u16 portid;
62ac0d32 1186 u32 i;
a07b4970
CH
1187
1188 if (kstrtou16(name, 0, &portid))
1189 return ERR_PTR(-EINVAL);
1190
1191 port = kzalloc(sizeof(*port), GFP_KERNEL);
1192 if (!port)
f98d9ca1 1193 return ERR_PTR(-ENOMEM);
a07b4970 1194
72efd25d
CH
1195 port->ana_state = kcalloc(NVMET_MAX_ANAGRPS + 1,
1196 sizeof(*port->ana_state), GFP_KERNEL);
1197 if (!port->ana_state) {
1198 kfree(port);
1199 return ERR_PTR(-ENOMEM);
1200 }
1201
62ac0d32
CH
1202 for (i = 1; i <= NVMET_MAX_ANAGRPS; i++) {
1203 if (i == NVMET_DEFAULT_ANA_GRPID)
1204 port->ana_state[1] = NVME_ANA_OPTIMIZED;
1205 else
1206 port->ana_state[i] = NVME_ANA_INACCESSIBLE;
1207 }
72efd25d 1208
b662a078
JS
1209 list_add(&port->global_entry, &nvmet_ports_list);
1210
a07b4970
CH
1211 INIT_LIST_HEAD(&port->entry);
1212 INIT_LIST_HEAD(&port->subsystems);
1213 INIT_LIST_HEAD(&port->referrals);
0d5ee2b2 1214 port->inline_data_size = -1; /* < 0 == let the transport choose */
a07b4970
CH
1215
1216 port->disc_addr.portid = cpu_to_le16(portid);
1217 config_group_init_type_name(&port->group, name, &nvmet_port_type);
1218
1219 config_group_init_type_name(&port->subsys_group,
1220 "subsystems", &nvmet_port_subsys_type);
1221 configfs_add_default_group(&port->subsys_group, &port->group);
1222
1223 config_group_init_type_name(&port->referrals_group,
1224 "referrals", &nvmet_referrals_type);
1225 configfs_add_default_group(&port->referrals_group, &port->group);
1226
62ac0d32
CH
1227 config_group_init_type_name(&port->ana_groups_group,
1228 "ana_groups", &nvmet_ana_groups_type);
1229 configfs_add_default_group(&port->ana_groups_group, &port->group);
1230
1231 port->ana_default_group.port = port;
1232 port->ana_default_group.grpid = NVMET_DEFAULT_ANA_GRPID;
1233 config_group_init_type_name(&port->ana_default_group.group,
1234 __stringify(NVMET_DEFAULT_ANA_GRPID),
1235 &nvmet_ana_group_type);
1236 configfs_add_default_group(&port->ana_default_group.group,
1237 &port->ana_groups_group);
1238
a07b4970
CH
1239 return &port->group;
1240}
1241
1242static struct configfs_group_operations nvmet_ports_group_ops = {
1243 .make_group = nvmet_ports_make,
1244};
1245
66603a31 1246static const struct config_item_type nvmet_ports_type = {
a07b4970
CH
1247 .ct_group_ops = &nvmet_ports_group_ops,
1248 .ct_owner = THIS_MODULE,
1249};
1250
1251static struct config_group nvmet_subsystems_group;
1252static struct config_group nvmet_ports_group;
1253
1254static void nvmet_host_release(struct config_item *item)
1255{
1256 struct nvmet_host *host = to_host(item);
1257
1258 kfree(host);
1259}
1260
1261static struct configfs_item_operations nvmet_host_item_ops = {
1262 .release = nvmet_host_release,
1263};
1264
66603a31 1265static const struct config_item_type nvmet_host_type = {
a07b4970
CH
1266 .ct_item_ops = &nvmet_host_item_ops,
1267 .ct_owner = THIS_MODULE,
1268};
1269
1270static struct config_group *nvmet_hosts_make_group(struct config_group *group,
1271 const char *name)
1272{
1273 struct nvmet_host *host;
1274
1275 host = kzalloc(sizeof(*host), GFP_KERNEL);
1276 if (!host)
1277 return ERR_PTR(-ENOMEM);
1278
1279 config_group_init_type_name(&host->group, name, &nvmet_host_type);
1280
1281 return &host->group;
1282}
1283
1284static struct configfs_group_operations nvmet_hosts_group_ops = {
1285 .make_group = nvmet_hosts_make_group,
1286};
1287
66603a31 1288static const struct config_item_type nvmet_hosts_type = {
a07b4970
CH
1289 .ct_group_ops = &nvmet_hosts_group_ops,
1290 .ct_owner = THIS_MODULE,
1291};
1292
1293static struct config_group nvmet_hosts_group;
1294
66603a31 1295static const struct config_item_type nvmet_root_type = {
a07b4970
CH
1296 .ct_owner = THIS_MODULE,
1297};
1298
1299static struct configfs_subsystem nvmet_configfs_subsystem = {
1300 .su_group = {
1301 .cg_item = {
1302 .ci_namebuf = "nvmet",
1303 .ci_type = &nvmet_root_type,
1304 },
1305 },
1306};
1307
1308int __init nvmet_init_configfs(void)
1309{
1310 int ret;
1311
1312 config_group_init(&nvmet_configfs_subsystem.su_group);
1313 mutex_init(&nvmet_configfs_subsystem.su_mutex);
1314
1315 config_group_init_type_name(&nvmet_subsystems_group,
1316 "subsystems", &nvmet_subsystems_type);
1317 configfs_add_default_group(&nvmet_subsystems_group,
1318 &nvmet_configfs_subsystem.su_group);
1319
1320 config_group_init_type_name(&nvmet_ports_group,
1321 "ports", &nvmet_ports_type);
1322 configfs_add_default_group(&nvmet_ports_group,
1323 &nvmet_configfs_subsystem.su_group);
1324
1325 config_group_init_type_name(&nvmet_hosts_group,
1326 "hosts", &nvmet_hosts_type);
1327 configfs_add_default_group(&nvmet_hosts_group,
1328 &nvmet_configfs_subsystem.su_group);
1329
1330 ret = configfs_register_subsystem(&nvmet_configfs_subsystem);
1331 if (ret) {
1332 pr_err("configfs_register_subsystem: %d\n", ret);
1333 return ret;
1334 }
1335
1336 return 0;
1337}
1338
1339void __exit nvmet_exit_configfs(void)
1340{
1341 configfs_unregister_subsystem(&nvmet_configfs_subsystem);
1342}