^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Configfs interface for the NVMe target.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2015-2016 HGST, a Western Digital Company.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/pci-p2pdma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "nvmet.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) static const struct config_item_type nvmet_host_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static const struct config_item_type nvmet_subsys_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static LIST_HEAD(nvmet_ports_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) struct list_head *nvmet_ports = &nvmet_ports_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct nvmet_type_name_map {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) u8 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static struct nvmet_type_name_map nvmet_transport[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) { NVMF_TRTYPE_RDMA, "rdma" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) { NVMF_TRTYPE_FC, "fc" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) { NVMF_TRTYPE_TCP, "tcp" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) { NVMF_TRTYPE_LOOP, "loop" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static const struct nvmet_type_name_map nvmet_addr_family[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) { NVMF_ADDR_FAMILY_PCI, "pcie" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) { NVMF_ADDR_FAMILY_IP4, "ipv4" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) { NVMF_ADDR_FAMILY_IP6, "ipv6" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) { NVMF_ADDR_FAMILY_IB, "ib" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) { NVMF_ADDR_FAMILY_FC, "fc" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) { NVMF_ADDR_FAMILY_LOOP, "loop" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static bool nvmet_is_port_enabled(struct nvmet_port *p, const char *caller)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if (p->enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) pr_err("Disable port '%u' before changing attribute in %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) le16_to_cpu(p->disc_addr.portid), caller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return p->enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * nvmet_port Generic ConfigFS definitions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * Used in any place in the ConfigFS tree that refers to an address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static ssize_t nvmet_addr_adrfam_show(struct config_item *item, char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) u8 adrfam = to_nvmet_port(item)->disc_addr.adrfam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) for (i = 1; i < ARRAY_SIZE(nvmet_addr_family); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (nvmet_addr_family[i].type == adrfam)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return sprintf(page, "%s\n", nvmet_addr_family[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) return sprintf(page, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static ssize_t nvmet_addr_adrfam_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct nvmet_port *port = to_nvmet_port(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (nvmet_is_port_enabled(port, __func__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) for (i = 1; i < ARRAY_SIZE(nvmet_addr_family); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (sysfs_streq(page, nvmet_addr_family[i].name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) pr_err("Invalid value '%s' for adrfam\n", page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) port->disc_addr.adrfam = nvmet_addr_family[i].type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) CONFIGFS_ATTR(nvmet_, addr_adrfam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static ssize_t nvmet_addr_portid_show(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct nvmet_port *port = to_nvmet_port(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return snprintf(page, PAGE_SIZE, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) le16_to_cpu(port->disc_addr.portid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static ssize_t nvmet_addr_portid_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct nvmet_port *port = to_nvmet_port(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) u16 portid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (kstrtou16(page, 0, &portid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) pr_err("Invalid value '%s' for portid\n", page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (nvmet_is_port_enabled(port, __func__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) port->disc_addr.portid = cpu_to_le16(portid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) CONFIGFS_ATTR(nvmet_, addr_portid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static ssize_t nvmet_addr_traddr_show(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct nvmet_port *port = to_nvmet_port(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return snprintf(page, PAGE_SIZE, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) port->disc_addr.traddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static ssize_t nvmet_addr_traddr_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct nvmet_port *port = to_nvmet_port(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (count > NVMF_TRADDR_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) pr_err("Invalid value '%s' for traddr\n", page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (nvmet_is_port_enabled(port, __func__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (sscanf(page, "%s\n", port->disc_addr.traddr) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) CONFIGFS_ATTR(nvmet_, addr_traddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static const struct nvmet_type_name_map nvmet_addr_treq[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) { NVMF_TREQ_NOT_SPECIFIED, "not specified" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) { NVMF_TREQ_REQUIRED, "required" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) { NVMF_TREQ_NOT_REQUIRED, "not required" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static ssize_t nvmet_addr_treq_show(struct config_item *item, char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) u8 treq = to_nvmet_port(item)->disc_addr.treq &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) NVME_TREQ_SECURE_CHANNEL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) for (i = 0; i < ARRAY_SIZE(nvmet_addr_treq); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (treq == nvmet_addr_treq[i].type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return sprintf(page, "%s\n", nvmet_addr_treq[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return sprintf(page, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static ssize_t nvmet_addr_treq_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct nvmet_port *port = to_nvmet_port(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) u8 treq = port->disc_addr.treq & ~NVME_TREQ_SECURE_CHANNEL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (nvmet_is_port_enabled(port, __func__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) for (i = 0; i < ARRAY_SIZE(nvmet_addr_treq); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (sysfs_streq(page, nvmet_addr_treq[i].name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) pr_err("Invalid value '%s' for treq\n", page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) treq |= nvmet_addr_treq[i].type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) port->disc_addr.treq = treq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) CONFIGFS_ATTR(nvmet_, addr_treq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static ssize_t nvmet_addr_trsvcid_show(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct nvmet_port *port = to_nvmet_port(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return snprintf(page, PAGE_SIZE, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) port->disc_addr.trsvcid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) static ssize_t nvmet_addr_trsvcid_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) struct nvmet_port *port = to_nvmet_port(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (count > NVMF_TRSVCID_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) pr_err("Invalid value '%s' for trsvcid\n", page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (nvmet_is_port_enabled(port, __func__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (sscanf(page, "%s\n", port->disc_addr.trsvcid) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) CONFIGFS_ATTR(nvmet_, addr_trsvcid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static ssize_t nvmet_param_inline_data_size_show(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) struct nvmet_port *port = to_nvmet_port(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return snprintf(page, PAGE_SIZE, "%d\n", port->inline_data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static ssize_t nvmet_param_inline_data_size_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) struct nvmet_port *port = to_nvmet_port(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (nvmet_is_port_enabled(port, __func__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) ret = kstrtoint(page, 0, &port->inline_data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) pr_err("Invalid value '%s' for inline_data_size\n", page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) CONFIGFS_ATTR(nvmet_, param_inline_data_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) #ifdef CONFIG_BLK_DEV_INTEGRITY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static ssize_t nvmet_param_pi_enable_show(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct nvmet_port *port = to_nvmet_port(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return snprintf(page, PAGE_SIZE, "%d\n", port->pi_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static ssize_t nvmet_param_pi_enable_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct nvmet_port *port = to_nvmet_port(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) bool val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (strtobool(page, &val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (port->enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) pr_err("Disable port before setting pi_enable value.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) port->pi_enable = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) CONFIGFS_ATTR(nvmet_, param_pi_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static ssize_t nvmet_addr_trtype_show(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) struct nvmet_port *port = to_nvmet_port(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) for (i = 0; i < ARRAY_SIZE(nvmet_transport); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (port->disc_addr.trtype == nvmet_transport[i].type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return sprintf(page, "%s\n", nvmet_transport[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return sprintf(page, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) static void nvmet_port_init_tsas_rdma(struct nvmet_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) port->disc_addr.tsas.rdma.qptype = NVMF_RDMA_QPTYPE_CONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) port->disc_addr.tsas.rdma.prtype = NVMF_RDMA_PRTYPE_NOT_SPECIFIED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) port->disc_addr.tsas.rdma.cms = NVMF_RDMA_CMS_RDMA_CM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) static ssize_t nvmet_addr_trtype_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct nvmet_port *port = to_nvmet_port(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (nvmet_is_port_enabled(port, __func__))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) for (i = 0; i < ARRAY_SIZE(nvmet_transport); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (sysfs_streq(page, nvmet_transport[i].name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) pr_err("Invalid value '%s' for trtype\n", page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) memset(&port->disc_addr.tsas, 0, NVMF_TSAS_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) port->disc_addr.trtype = nvmet_transport[i].type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (port->disc_addr.trtype == NVMF_TRTYPE_RDMA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) nvmet_port_init_tsas_rdma(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) CONFIGFS_ATTR(nvmet_, addr_trtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * Namespace structures & file operation functions below
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static ssize_t nvmet_ns_device_path_show(struct config_item *item, char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return sprintf(page, "%s\n", to_nvmet_ns(item)->device_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) static ssize_t nvmet_ns_device_path_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) struct nvmet_ns *ns = to_nvmet_ns(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct nvmet_subsys *subsys = ns->subsys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) mutex_lock(&subsys->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (ns->enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) len = strcspn(page, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) kfree(ns->device_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) ns->device_path = kmemdup_nul(page, len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (!ns->device_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) mutex_unlock(&subsys->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) mutex_unlock(&subsys->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) CONFIGFS_ATTR(nvmet_ns_, device_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) #ifdef CONFIG_PCI_P2PDMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) static ssize_t nvmet_ns_p2pmem_show(struct config_item *item, char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) struct nvmet_ns *ns = to_nvmet_ns(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return pci_p2pdma_enable_show(page, ns->p2p_dev, ns->use_p2pmem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) static ssize_t nvmet_ns_p2pmem_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) struct nvmet_ns *ns = to_nvmet_ns(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) struct pci_dev *p2p_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) bool use_p2pmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) int ret = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) mutex_lock(&ns->subsys->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (ns->enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) error = pci_p2pdma_enable_store(page, &p2p_dev, &use_p2pmem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) ret = error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) ns->use_p2pmem = use_p2pmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) pci_dev_put(ns->p2p_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) ns->p2p_dev = p2p_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) mutex_unlock(&ns->subsys->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) CONFIGFS_ATTR(nvmet_ns_, p2pmem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) #endif /* CONFIG_PCI_P2PDMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) static ssize_t nvmet_ns_device_uuid_show(struct config_item *item, char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return sprintf(page, "%pUb\n", &to_nvmet_ns(item)->uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) static ssize_t nvmet_ns_device_uuid_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) struct nvmet_ns *ns = to_nvmet_ns(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) struct nvmet_subsys *subsys = ns->subsys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) mutex_lock(&subsys->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (ns->enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (uuid_parse(page, &ns->uuid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) mutex_unlock(&subsys->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return ret ? ret : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) CONFIGFS_ATTR(nvmet_ns_, device_uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) static ssize_t nvmet_ns_device_nguid_show(struct config_item *item, char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return sprintf(page, "%pUb\n", &to_nvmet_ns(item)->nguid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) static ssize_t nvmet_ns_device_nguid_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) struct nvmet_ns *ns = to_nvmet_ns(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) struct nvmet_subsys *subsys = ns->subsys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) u8 nguid[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) const char *p = page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) mutex_lock(&subsys->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (ns->enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) for (i = 0; i < 16; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (p + 2 > page + count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (!isxdigit(p[0]) || !isxdigit(p[1])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) nguid[i] = (hex_to_bin(p[0]) << 4) | hex_to_bin(p[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) p += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (*p == '-' || *p == ':')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) memcpy(&ns->nguid, nguid, sizeof(nguid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) mutex_unlock(&subsys->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return ret ? ret : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) CONFIGFS_ATTR(nvmet_ns_, device_nguid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) static ssize_t nvmet_ns_ana_grpid_show(struct config_item *item, char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return sprintf(page, "%u\n", to_nvmet_ns(item)->anagrpid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) static ssize_t nvmet_ns_ana_grpid_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) struct nvmet_ns *ns = to_nvmet_ns(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) u32 oldgrpid, newgrpid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) ret = kstrtou32(page, 0, &newgrpid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (newgrpid < 1 || newgrpid > NVMET_MAX_ANAGRPS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) down_write(&nvmet_ana_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) oldgrpid = ns->anagrpid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) nvmet_ana_group_enabled[newgrpid]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) ns->anagrpid = newgrpid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) nvmet_ana_group_enabled[oldgrpid]--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) nvmet_ana_chgcnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) up_write(&nvmet_ana_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) nvmet_send_ana_event(ns->subsys, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) CONFIGFS_ATTR(nvmet_ns_, ana_grpid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) static ssize_t nvmet_ns_enable_show(struct config_item *item, char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) return sprintf(page, "%d\n", to_nvmet_ns(item)->enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) static ssize_t nvmet_ns_enable_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) struct nvmet_ns *ns = to_nvmet_ns(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) bool enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (strtobool(page, &enable))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) ret = nvmet_ns_enable(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) nvmet_ns_disable(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return ret ? ret : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) CONFIGFS_ATTR(nvmet_ns_, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) static ssize_t nvmet_ns_buffered_io_show(struct config_item *item, char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) return sprintf(page, "%d\n", to_nvmet_ns(item)->buffered_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) static ssize_t nvmet_ns_buffered_io_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) struct nvmet_ns *ns = to_nvmet_ns(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) bool val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (strtobool(page, &val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) mutex_lock(&ns->subsys->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (ns->enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) pr_err("disable ns before setting buffered_io value.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) mutex_unlock(&ns->subsys->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) ns->buffered_io = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) mutex_unlock(&ns->subsys->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) CONFIGFS_ATTR(nvmet_ns_, buffered_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) static ssize_t nvmet_ns_revalidate_size_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) struct nvmet_ns *ns = to_nvmet_ns(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) bool val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (strtobool(page, &val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) mutex_lock(&ns->subsys->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (!ns->enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) pr_err("enable ns before revalidate.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) mutex_unlock(&ns->subsys->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) nvmet_ns_revalidate(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) mutex_unlock(&ns->subsys->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) CONFIGFS_ATTR_WO(nvmet_ns_, revalidate_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) static struct configfs_attribute *nvmet_ns_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) &nvmet_ns_attr_device_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) &nvmet_ns_attr_device_nguid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) &nvmet_ns_attr_device_uuid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) &nvmet_ns_attr_ana_grpid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) &nvmet_ns_attr_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) &nvmet_ns_attr_buffered_io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) &nvmet_ns_attr_revalidate_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) #ifdef CONFIG_PCI_P2PDMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) &nvmet_ns_attr_p2pmem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) static void nvmet_ns_release(struct config_item *item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) struct nvmet_ns *ns = to_nvmet_ns(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) nvmet_ns_free(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) static struct configfs_item_operations nvmet_ns_item_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) .release = nvmet_ns_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) static const struct config_item_type nvmet_ns_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) .ct_item_ops = &nvmet_ns_item_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) .ct_attrs = nvmet_ns_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) .ct_owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) static struct config_group *nvmet_ns_make(struct config_group *group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) struct nvmet_subsys *subsys = namespaces_to_subsys(&group->cg_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) struct nvmet_ns *ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) u32 nsid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) ret = kstrtou32(name, 0, &nsid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) if (nsid == 0 || nsid == NVME_NSID_ALL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) pr_err("invalid nsid %#x", nsid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) ns = nvmet_ns_alloc(subsys, nsid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) if (!ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) config_group_init_type_name(&ns->group, name, &nvmet_ns_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) pr_info("adding nsid %d to subsystem %s\n", nsid, subsys->subsysnqn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) return &ns->group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) static struct configfs_group_operations nvmet_namespaces_group_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) .make_group = nvmet_ns_make,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) static const struct config_item_type nvmet_namespaces_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) .ct_group_ops = &nvmet_namespaces_group_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) .ct_owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) #ifdef CONFIG_NVME_TARGET_PASSTHRU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) static ssize_t nvmet_passthru_device_path_show(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) struct nvmet_subsys *subsys = to_subsys(item->ci_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return snprintf(page, PAGE_SIZE, "%s\n", subsys->passthru_ctrl_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) static ssize_t nvmet_passthru_device_path_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) struct nvmet_subsys *subsys = to_subsys(item->ci_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) mutex_lock(&subsys->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (subsys->passthru_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) len = strcspn(page, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) kfree(subsys->passthru_ctrl_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) subsys->passthru_ctrl_path = kstrndup(page, len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (!subsys->passthru_ctrl_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) mutex_unlock(&subsys->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) mutex_unlock(&subsys->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) CONFIGFS_ATTR(nvmet_passthru_, device_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) static ssize_t nvmet_passthru_enable_show(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) struct nvmet_subsys *subsys = to_subsys(item->ci_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) return sprintf(page, "%d\n", subsys->passthru_ctrl ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) static ssize_t nvmet_passthru_enable_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) struct nvmet_subsys *subsys = to_subsys(item->ci_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) bool enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (strtobool(page, &enable))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) ret = nvmet_passthru_ctrl_enable(subsys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) nvmet_passthru_ctrl_disable(subsys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) return ret ? ret : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) CONFIGFS_ATTR(nvmet_passthru_, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) static struct configfs_attribute *nvmet_passthru_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) &nvmet_passthru_attr_device_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) &nvmet_passthru_attr_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) static const struct config_item_type nvmet_passthru_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) .ct_attrs = nvmet_passthru_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) .ct_owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) static void nvmet_add_passthru_group(struct nvmet_subsys *subsys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) config_group_init_type_name(&subsys->passthru_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) "passthru", &nvmet_passthru_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) configfs_add_default_group(&subsys->passthru_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) &subsys->group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) #else /* CONFIG_NVME_TARGET_PASSTHRU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) static void nvmet_add_passthru_group(struct nvmet_subsys *subsys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) #endif /* CONFIG_NVME_TARGET_PASSTHRU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) static int nvmet_port_subsys_allow_link(struct config_item *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) struct config_item *target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) struct nvmet_port *port = to_nvmet_port(parent->ci_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) struct nvmet_subsys *subsys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) struct nvmet_subsys_link *link, *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (target->ci_type != &nvmet_subsys_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) pr_err("can only link subsystems into the subsystems dir.!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) subsys = to_subsys(target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) link = kmalloc(sizeof(*link), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (!link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) link->subsys = subsys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) down_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) ret = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) list_for_each_entry(p, &port->subsystems, entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (p->subsys == subsys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) goto out_free_link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) if (list_empty(&port->subsystems)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) ret = nvmet_enable_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) goto out_free_link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) list_add_tail(&link->entry, &port->subsystems);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) nvmet_port_disc_changed(port, subsys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) up_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) out_free_link:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) up_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) kfree(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) static void nvmet_port_subsys_drop_link(struct config_item *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) struct config_item *target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) struct nvmet_port *port = to_nvmet_port(parent->ci_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) struct nvmet_subsys *subsys = to_subsys(target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) struct nvmet_subsys_link *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) down_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) list_for_each_entry(p, &port->subsystems, entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (p->subsys == subsys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) up_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) list_del(&p->entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) nvmet_port_del_ctrls(port, subsys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) nvmet_port_disc_changed(port, subsys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) if (list_empty(&port->subsystems))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) nvmet_disable_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) up_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) kfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) static struct configfs_item_operations nvmet_port_subsys_item_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) .allow_link = nvmet_port_subsys_allow_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) .drop_link = nvmet_port_subsys_drop_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) static const struct config_item_type nvmet_port_subsys_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) .ct_item_ops = &nvmet_port_subsys_item_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) .ct_owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) static int nvmet_allowed_hosts_allow_link(struct config_item *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) struct config_item *target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) struct nvmet_subsys *subsys = to_subsys(parent->ci_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) struct nvmet_host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) struct nvmet_host_link *link, *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if (target->ci_type != &nvmet_host_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) pr_err("can only link hosts into the allowed_hosts directory!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) host = to_host(target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) link = kmalloc(sizeof(*link), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) if (!link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) link->host = host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) down_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (subsys->allow_any_host) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) pr_err("can't add hosts when allow_any_host is set!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) goto out_free_link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) ret = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) list_for_each_entry(p, &subsys->hosts, entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) if (!strcmp(nvmet_host_name(p->host), nvmet_host_name(host)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) goto out_free_link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) list_add_tail(&link->entry, &subsys->hosts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) nvmet_subsys_disc_changed(subsys, host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) up_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) out_free_link:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) up_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) kfree(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) static void nvmet_allowed_hosts_drop_link(struct config_item *parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) struct config_item *target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) struct nvmet_subsys *subsys = to_subsys(parent->ci_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) struct nvmet_host *host = to_host(target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) struct nvmet_host_link *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) down_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) list_for_each_entry(p, &subsys->hosts, entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) if (!strcmp(nvmet_host_name(p->host), nvmet_host_name(host)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) up_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) list_del(&p->entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) nvmet_subsys_disc_changed(subsys, host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) up_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) kfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) static struct configfs_item_operations nvmet_allowed_hosts_item_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) .allow_link = nvmet_allowed_hosts_allow_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) .drop_link = nvmet_allowed_hosts_drop_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) static const struct config_item_type nvmet_allowed_hosts_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) .ct_item_ops = &nvmet_allowed_hosts_item_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) .ct_owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) static ssize_t nvmet_subsys_attr_allow_any_host_show(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) return snprintf(page, PAGE_SIZE, "%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) to_subsys(item)->allow_any_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) static ssize_t nvmet_subsys_attr_allow_any_host_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) struct nvmet_subsys *subsys = to_subsys(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) bool allow_any_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) if (strtobool(page, &allow_any_host))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) down_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (allow_any_host && !list_empty(&subsys->hosts)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) pr_err("Can't set allow_any_host when explicit hosts are set!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) if (subsys->allow_any_host != allow_any_host) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) subsys->allow_any_host = allow_any_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) nvmet_subsys_disc_changed(subsys, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) up_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) return ret ? ret : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) CONFIGFS_ATTR(nvmet_subsys_, attr_allow_any_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) static ssize_t nvmet_subsys_attr_version_show(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) struct nvmet_subsys *subsys = to_subsys(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) if (NVME_TERTIARY(subsys->ver))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) return snprintf(page, PAGE_SIZE, "%llu.%llu.%llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) NVME_MAJOR(subsys->ver),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) NVME_MINOR(subsys->ver),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) NVME_TERTIARY(subsys->ver));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) return snprintf(page, PAGE_SIZE, "%llu.%llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) NVME_MAJOR(subsys->ver),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) NVME_MINOR(subsys->ver));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) static ssize_t nvmet_subsys_attr_version_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) struct nvmet_subsys *subsys = to_subsys(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) int major, minor, tertiary = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) /* passthru subsystems use the underlying controller's version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) if (nvmet_passthru_ctrl(subsys))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) ret = sscanf(page, "%d.%d.%d\n", &major, &minor, &tertiary);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (ret != 2 && ret != 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) down_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) subsys->ver = NVME_VS(major, minor, tertiary);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) up_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) CONFIGFS_ATTR(nvmet_subsys_, attr_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) static ssize_t nvmet_subsys_attr_serial_show(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) struct nvmet_subsys *subsys = to_subsys(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) return snprintf(page, PAGE_SIZE, "%llx\n", subsys->serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) static ssize_t nvmet_subsys_attr_serial_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) u64 serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) if (sscanf(page, "%llx\n", &serial) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) down_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) to_subsys(item)->serial = serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) up_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) CONFIGFS_ATTR(nvmet_subsys_, attr_serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) static ssize_t nvmet_subsys_attr_cntlid_min_show(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) return snprintf(page, PAGE_SIZE, "%u\n", to_subsys(item)->cntlid_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) static ssize_t nvmet_subsys_attr_cntlid_min_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) const char *page, size_t cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) u16 cntlid_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) if (sscanf(page, "%hu\n", &cntlid_min) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) if (cntlid_min == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) down_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) if (cntlid_min >= to_subsys(item)->cntlid_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) to_subsys(item)->cntlid_min = cntlid_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) up_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) return cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) up_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) CONFIGFS_ATTR(nvmet_subsys_, attr_cntlid_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) static ssize_t nvmet_subsys_attr_cntlid_max_show(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) return snprintf(page, PAGE_SIZE, "%u\n", to_subsys(item)->cntlid_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) static ssize_t nvmet_subsys_attr_cntlid_max_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) const char *page, size_t cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) u16 cntlid_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) if (sscanf(page, "%hu\n", &cntlid_max) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) if (cntlid_max == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) down_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (cntlid_max <= to_subsys(item)->cntlid_min)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) to_subsys(item)->cntlid_max = cntlid_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) up_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) return cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) up_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) CONFIGFS_ATTR(nvmet_subsys_, attr_cntlid_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) static ssize_t nvmet_subsys_attr_model_show(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) struct nvmet_subsys *subsys = to_subsys(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) struct nvmet_subsys_model *subsys_model;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) char *model = NVMET_DEFAULT_CTRL_MODEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) subsys_model = rcu_dereference(subsys->model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) if (subsys_model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) model = subsys_model->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) ret = snprintf(page, PAGE_SIZE, "%s\n", model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) /* See Section 1.5 of NVMe 1.4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) static bool nvmet_is_ascii(const char c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) return c >= 0x20 && c <= 0x7e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) static ssize_t nvmet_subsys_attr_model_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) struct nvmet_subsys *subsys = to_subsys(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) struct nvmet_subsys_model *new_model;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) char *new_model_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) int pos = 0, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) len = strcspn(page, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) for (pos = 0; pos < len; pos++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) if (!nvmet_is_ascii(page[pos]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) new_model_number = kmemdup_nul(page, len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) if (!new_model_number)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) new_model = kzalloc(sizeof(*new_model) + len + 1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) if (!new_model) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) kfree(new_model_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) memcpy(new_model->number, new_model_number, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) down_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) mutex_lock(&subsys->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) new_model = rcu_replace_pointer(subsys->model, new_model,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) mutex_is_locked(&subsys->lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) mutex_unlock(&subsys->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) up_write(&nvmet_config_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) kfree_rcu(new_model, rcuhead);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) kfree(new_model_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) CONFIGFS_ATTR(nvmet_subsys_, attr_model);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) #ifdef CONFIG_BLK_DEV_INTEGRITY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) static ssize_t nvmet_subsys_attr_pi_enable_show(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) return snprintf(page, PAGE_SIZE, "%d\n", to_subsys(item)->pi_support);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) static ssize_t nvmet_subsys_attr_pi_enable_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) struct nvmet_subsys *subsys = to_subsys(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) bool pi_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) if (strtobool(page, &pi_enable))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) subsys->pi_support = pi_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) CONFIGFS_ATTR(nvmet_subsys_, attr_pi_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) static struct configfs_attribute *nvmet_subsys_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) &nvmet_subsys_attr_attr_allow_any_host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) &nvmet_subsys_attr_attr_version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) &nvmet_subsys_attr_attr_serial,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) &nvmet_subsys_attr_attr_cntlid_min,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) &nvmet_subsys_attr_attr_cntlid_max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) &nvmet_subsys_attr_attr_model,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) #ifdef CONFIG_BLK_DEV_INTEGRITY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) &nvmet_subsys_attr_attr_pi_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) * Subsystem structures & folder operation functions below
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) static void nvmet_subsys_release(struct config_item *item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) struct nvmet_subsys *subsys = to_subsys(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) nvmet_subsys_del_ctrls(subsys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) nvmet_subsys_put(subsys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) static struct configfs_item_operations nvmet_subsys_item_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) .release = nvmet_subsys_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) static const struct config_item_type nvmet_subsys_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) .ct_item_ops = &nvmet_subsys_item_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) .ct_attrs = nvmet_subsys_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) .ct_owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) static struct config_group *nvmet_subsys_make(struct config_group *group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) struct nvmet_subsys *subsys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) if (sysfs_streq(name, NVME_DISC_SUBSYS_NAME)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) pr_err("can't create discovery subsystem through configfs\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) subsys = nvmet_subsys_alloc(name, NVME_NQN_NVME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) if (IS_ERR(subsys))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) return ERR_CAST(subsys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) config_group_init_type_name(&subsys->group, name, &nvmet_subsys_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) config_group_init_type_name(&subsys->namespaces_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) "namespaces", &nvmet_namespaces_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) configfs_add_default_group(&subsys->namespaces_group, &subsys->group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) config_group_init_type_name(&subsys->allowed_hosts_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) "allowed_hosts", &nvmet_allowed_hosts_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) configfs_add_default_group(&subsys->allowed_hosts_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) &subsys->group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) nvmet_add_passthru_group(subsys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) return &subsys->group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) static struct configfs_group_operations nvmet_subsystems_group_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) .make_group = nvmet_subsys_make,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) static const struct config_item_type nvmet_subsystems_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) .ct_group_ops = &nvmet_subsystems_group_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) .ct_owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) static ssize_t nvmet_referral_enable_show(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) return snprintf(page, PAGE_SIZE, "%d\n", to_nvmet_port(item)->enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) static ssize_t nvmet_referral_enable_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) struct nvmet_port *parent = to_nvmet_port(item->ci_parent->ci_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) struct nvmet_port *port = to_nvmet_port(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) bool enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) if (strtobool(page, &enable))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) goto inval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) nvmet_referral_enable(parent, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) nvmet_referral_disable(parent, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) inval:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) pr_err("Invalid value '%s' for enable\n", page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) CONFIGFS_ATTR(nvmet_referral_, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) * Discovery Service subsystem definitions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) static struct configfs_attribute *nvmet_referral_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) &nvmet_attr_addr_adrfam,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) &nvmet_attr_addr_portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) &nvmet_attr_addr_treq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) &nvmet_attr_addr_traddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) &nvmet_attr_addr_trsvcid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) &nvmet_attr_addr_trtype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) &nvmet_referral_attr_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) static void nvmet_referral_notify(struct config_group *group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) struct config_item *item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) struct nvmet_port *parent = to_nvmet_port(item->ci_parent->ci_parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) struct nvmet_port *port = to_nvmet_port(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) nvmet_referral_disable(parent, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) static void nvmet_referral_release(struct config_item *item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) struct nvmet_port *port = to_nvmet_port(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) kfree(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) static struct configfs_item_operations nvmet_referral_item_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) .release = nvmet_referral_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) static const struct config_item_type nvmet_referral_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) .ct_owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) .ct_attrs = nvmet_referral_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) .ct_item_ops = &nvmet_referral_item_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) static struct config_group *nvmet_referral_make(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) struct config_group *group, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) struct nvmet_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) port = kzalloc(sizeof(*port), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) if (!port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) INIT_LIST_HEAD(&port->entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) config_group_init_type_name(&port->group, name, &nvmet_referral_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) return &port->group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) static struct configfs_group_operations nvmet_referral_group_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) .make_group = nvmet_referral_make,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) .disconnect_notify = nvmet_referral_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) static const struct config_item_type nvmet_referrals_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) .ct_owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) .ct_group_ops = &nvmet_referral_group_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) static struct nvmet_type_name_map nvmet_ana_state[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) { NVME_ANA_OPTIMIZED, "optimized" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) { NVME_ANA_NONOPTIMIZED, "non-optimized" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) { NVME_ANA_INACCESSIBLE, "inaccessible" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) { NVME_ANA_PERSISTENT_LOSS, "persistent-loss" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) { NVME_ANA_CHANGE, "change" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) static ssize_t nvmet_ana_group_ana_state_show(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) struct nvmet_ana_group *grp = to_ana_group(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) enum nvme_ana_state state = grp->port->ana_state[grp->grpid];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) for (i = 0; i < ARRAY_SIZE(nvmet_ana_state); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) if (state == nvmet_ana_state[i].type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) return sprintf(page, "%s\n", nvmet_ana_state[i].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) return sprintf(page, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) static ssize_t nvmet_ana_group_ana_state_store(struct config_item *item,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) const char *page, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) struct nvmet_ana_group *grp = to_ana_group(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) enum nvme_ana_state *ana_state = grp->port->ana_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) for (i = 0; i < ARRAY_SIZE(nvmet_ana_state); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) if (sysfs_streq(page, nvmet_ana_state[i].name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) pr_err("Invalid value '%s' for ana_state\n", page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) down_write(&nvmet_ana_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) ana_state[grp->grpid] = (enum nvme_ana_state) nvmet_ana_state[i].type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) nvmet_ana_chgcnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) up_write(&nvmet_ana_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) nvmet_port_send_ana_event(grp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) CONFIGFS_ATTR(nvmet_ana_group_, ana_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) static struct configfs_attribute *nvmet_ana_group_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) &nvmet_ana_group_attr_ana_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) static void nvmet_ana_group_release(struct config_item *item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) struct nvmet_ana_group *grp = to_ana_group(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) if (grp == &grp->port->ana_default_group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) down_write(&nvmet_ana_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) grp->port->ana_state[grp->grpid] = NVME_ANA_INACCESSIBLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) nvmet_ana_group_enabled[grp->grpid]--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) up_write(&nvmet_ana_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) nvmet_port_send_ana_event(grp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) kfree(grp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) static struct configfs_item_operations nvmet_ana_group_item_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) .release = nvmet_ana_group_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) static const struct config_item_type nvmet_ana_group_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) .ct_item_ops = &nvmet_ana_group_item_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) .ct_attrs = nvmet_ana_group_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) .ct_owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) static struct config_group *nvmet_ana_groups_make_group(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) struct config_group *group, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) struct nvmet_port *port = ana_groups_to_port(&group->cg_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) struct nvmet_ana_group *grp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) u32 grpid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) ret = kstrtou32(name, 0, &grpid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) if (grpid <= 1 || grpid > NVMET_MAX_ANAGRPS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) grp = kzalloc(sizeof(*grp), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) if (!grp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) grp->port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) grp->grpid = grpid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) down_write(&nvmet_ana_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) nvmet_ana_group_enabled[grpid]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) up_write(&nvmet_ana_sem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) nvmet_port_send_ana_event(grp->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) config_group_init_type_name(&grp->group, name, &nvmet_ana_group_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) return &grp->group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) static struct configfs_group_operations nvmet_ana_groups_group_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) .make_group = nvmet_ana_groups_make_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) static const struct config_item_type nvmet_ana_groups_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) .ct_group_ops = &nvmet_ana_groups_group_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) .ct_owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) * Ports definitions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) static void nvmet_port_release(struct config_item *item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) struct nvmet_port *port = to_nvmet_port(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) /* Let inflight controllers teardown complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) flush_scheduled_work();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) list_del(&port->global_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) kfree(port->ana_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) kfree(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) static struct configfs_attribute *nvmet_port_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) &nvmet_attr_addr_adrfam,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) &nvmet_attr_addr_treq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) &nvmet_attr_addr_traddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) &nvmet_attr_addr_trsvcid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) &nvmet_attr_addr_trtype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) &nvmet_attr_param_inline_data_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) #ifdef CONFIG_BLK_DEV_INTEGRITY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) &nvmet_attr_param_pi_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) static struct configfs_item_operations nvmet_port_item_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) .release = nvmet_port_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) static const struct config_item_type nvmet_port_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) .ct_attrs = nvmet_port_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) .ct_item_ops = &nvmet_port_item_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) .ct_owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) static struct config_group *nvmet_ports_make(struct config_group *group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) struct nvmet_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) u16 portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) if (kstrtou16(name, 0, &portid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) port = kzalloc(sizeof(*port), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) if (!port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) port->ana_state = kcalloc(NVMET_MAX_ANAGRPS + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) sizeof(*port->ana_state), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) if (!port->ana_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) kfree(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) for (i = 1; i <= NVMET_MAX_ANAGRPS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) if (i == NVMET_DEFAULT_ANA_GRPID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) port->ana_state[1] = NVME_ANA_OPTIMIZED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) port->ana_state[i] = NVME_ANA_INACCESSIBLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) list_add(&port->global_entry, &nvmet_ports_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) INIT_LIST_HEAD(&port->entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) INIT_LIST_HEAD(&port->subsystems);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) INIT_LIST_HEAD(&port->referrals);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) port->inline_data_size = -1; /* < 0 == let the transport choose */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) port->disc_addr.portid = cpu_to_le16(portid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) port->disc_addr.adrfam = NVMF_ADDR_FAMILY_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) port->disc_addr.treq = NVMF_TREQ_DISABLE_SQFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) config_group_init_type_name(&port->group, name, &nvmet_port_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) config_group_init_type_name(&port->subsys_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) "subsystems", &nvmet_port_subsys_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) configfs_add_default_group(&port->subsys_group, &port->group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) config_group_init_type_name(&port->referrals_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) "referrals", &nvmet_referrals_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) configfs_add_default_group(&port->referrals_group, &port->group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) config_group_init_type_name(&port->ana_groups_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) "ana_groups", &nvmet_ana_groups_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) configfs_add_default_group(&port->ana_groups_group, &port->group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) port->ana_default_group.port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) port->ana_default_group.grpid = NVMET_DEFAULT_ANA_GRPID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) config_group_init_type_name(&port->ana_default_group.group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) __stringify(NVMET_DEFAULT_ANA_GRPID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) &nvmet_ana_group_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) configfs_add_default_group(&port->ana_default_group.group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) &port->ana_groups_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) return &port->group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) static struct configfs_group_operations nvmet_ports_group_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) .make_group = nvmet_ports_make,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) static const struct config_item_type nvmet_ports_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) .ct_group_ops = &nvmet_ports_group_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) .ct_owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) static struct config_group nvmet_subsystems_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) static struct config_group nvmet_ports_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) static void nvmet_host_release(struct config_item *item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) struct nvmet_host *host = to_host(item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) kfree(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) static struct configfs_item_operations nvmet_host_item_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) .release = nvmet_host_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) static const struct config_item_type nvmet_host_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) .ct_item_ops = &nvmet_host_item_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) .ct_owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) static struct config_group *nvmet_hosts_make_group(struct config_group *group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) struct nvmet_host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) host = kzalloc(sizeof(*host), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) if (!host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) config_group_init_type_name(&host->group, name, &nvmet_host_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) return &host->group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) static struct configfs_group_operations nvmet_hosts_group_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) .make_group = nvmet_hosts_make_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) static const struct config_item_type nvmet_hosts_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) .ct_group_ops = &nvmet_hosts_group_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) .ct_owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) static struct config_group nvmet_hosts_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) static const struct config_item_type nvmet_root_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) .ct_owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) static struct configfs_subsystem nvmet_configfs_subsystem = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) .su_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) .cg_item = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) .ci_namebuf = "nvmet",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) .ci_type = &nvmet_root_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) int __init nvmet_init_configfs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) config_group_init(&nvmet_configfs_subsystem.su_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) mutex_init(&nvmet_configfs_subsystem.su_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) config_group_init_type_name(&nvmet_subsystems_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) "subsystems", &nvmet_subsystems_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) configfs_add_default_group(&nvmet_subsystems_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) &nvmet_configfs_subsystem.su_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) config_group_init_type_name(&nvmet_ports_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) "ports", &nvmet_ports_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) configfs_add_default_group(&nvmet_ports_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) &nvmet_configfs_subsystem.su_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) config_group_init_type_name(&nvmet_hosts_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) "hosts", &nvmet_hosts_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) configfs_add_default_group(&nvmet_hosts_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) &nvmet_configfs_subsystem.su_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) ret = configfs_register_subsystem(&nvmet_configfs_subsystem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) pr_err("configfs_register_subsystem: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) void __exit nvmet_exit_configfs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) configfs_unregister_subsystem(&nvmet_configfs_subsystem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) }