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