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