linux/drivers/nvdimm/label.c
<<
>>
Prefs
   1/*
   2 * Copyright(c) 2013-2015 Intel Corporation. All rights reserved.
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of version 2 of the GNU General Public License as
   6 * published by the Free Software Foundation.
   7 *
   8 * This program is distributed in the hope that it will be useful, but
   9 * WITHOUT ANY WARRANTY; without even the implied warranty of
  10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11 * General Public License for more details.
  12 */
  13#include <linux/device.h>
  14#include <linux/ndctl.h>
  15#include <linux/uuid.h>
  16#include <linux/slab.h>
  17#include <linux/io.h>
  18#include <linux/nd.h>
  19#include "nd-core.h"
  20#include "label.h"
  21#include "nd.h"
  22
  23static guid_t nvdimm_btt_guid;
  24static guid_t nvdimm_btt2_guid;
  25static guid_t nvdimm_pfn_guid;
  26static guid_t nvdimm_dax_guid;
  27
  28static u32 best_seq(u32 a, u32 b)
  29{
  30        a &= NSINDEX_SEQ_MASK;
  31        b &= NSINDEX_SEQ_MASK;
  32
  33        if (a == 0 || a == b)
  34                return b;
  35        else if (b == 0)
  36                return a;
  37        else if (nd_inc_seq(a) == b)
  38                return b;
  39        else
  40                return a;
  41}
  42
  43unsigned sizeof_namespace_label(struct nvdimm_drvdata *ndd)
  44{
  45        return ndd->nslabel_size;
  46}
  47
  48static size_t __sizeof_namespace_index(u32 nslot)
  49{
  50        return ALIGN(sizeof(struct nd_namespace_index) + DIV_ROUND_UP(nslot, 8),
  51                        NSINDEX_ALIGN);
  52}
  53
  54static int __nvdimm_num_label_slots(struct nvdimm_drvdata *ndd,
  55                size_t index_size)
  56{
  57        return (ndd->nsarea.config_size - index_size * 2) /
  58                        sizeof_namespace_label(ndd);
  59}
  60
  61int nvdimm_num_label_slots(struct nvdimm_drvdata *ndd)
  62{
  63        u32 tmp_nslot, n;
  64
  65        tmp_nslot = ndd->nsarea.config_size / sizeof_namespace_label(ndd);
  66        n = __sizeof_namespace_index(tmp_nslot) / NSINDEX_ALIGN;
  67
  68        return __nvdimm_num_label_slots(ndd, NSINDEX_ALIGN * n);
  69}
  70
  71size_t sizeof_namespace_index(struct nvdimm_drvdata *ndd)
  72{
  73        u32 nslot, space, size;
  74
  75        /*
  76         * Per UEFI 2.7, the minimum size of the Label Storage Area is large
  77         * enough to hold 2 index blocks and 2 labels.  The minimum index
  78         * block size is 256 bytes, and the minimum label size is 256 bytes.
  79         */
  80        nslot = nvdimm_num_label_slots(ndd);
  81        space = ndd->nsarea.config_size - nslot * sizeof_namespace_label(ndd);
  82        size = __sizeof_namespace_index(nslot) * 2;
  83        if (size <= space && nslot >= 2)
  84                return size / 2;
  85
  86        dev_err(ndd->dev, "label area (%d) too small to host (%d byte) labels\n",
  87                        ndd->nsarea.config_size, sizeof_namespace_label(ndd));
  88        return 0;
  89}
  90
  91static int __nd_label_validate(struct nvdimm_drvdata *ndd)
  92{
  93        /*
  94         * On media label format consists of two index blocks followed
  95         * by an array of labels.  None of these structures are ever
  96         * updated in place.  A sequence number tracks the current
  97         * active index and the next one to write, while labels are
  98         * written to free slots.
  99         *
 100         *     +------------+
 101         *     |            |
 102         *     |  nsindex0  |
 103         *     |            |
 104         *     +------------+
 105         *     |            |
 106         *     |  nsindex1  |
 107         *     |            |
 108         *     +------------+
 109         *     |   label0   |
 110         *     +------------+
 111         *     |   label1   |
 112         *     +------------+
 113         *     |            |
 114         *      ....nslot...
 115         *     |            |
 116         *     +------------+
 117         *     |   labelN   |
 118         *     +------------+
 119         */
 120        struct nd_namespace_index *nsindex[] = {
 121                to_namespace_index(ndd, 0),
 122                to_namespace_index(ndd, 1),
 123        };
 124        const int num_index = ARRAY_SIZE(nsindex);
 125        struct device *dev = ndd->dev;
 126        bool valid[2] = { 0 };
 127        int i, num_valid = 0;
 128        u32 seq;
 129
 130        for (i = 0; i < num_index; i++) {
 131                u32 nslot;
 132                u8 sig[NSINDEX_SIG_LEN];
 133                u64 sum_save, sum, size;
 134                unsigned int version, labelsize;
 135
 136                memcpy(sig, nsindex[i]->sig, NSINDEX_SIG_LEN);
 137                if (memcmp(sig, NSINDEX_SIGNATURE, NSINDEX_SIG_LEN) != 0) {
 138                        dev_dbg(dev, "nsindex%d signature invalid\n", i);
 139                        continue;
 140                }
 141
 142                /* label sizes larger than 128 arrived with v1.2 */
 143                version = __le16_to_cpu(nsindex[i]->major) * 100
 144                        + __le16_to_cpu(nsindex[i]->minor);
 145                if (version >= 102)
 146                        labelsize = 1 << (7 + nsindex[i]->labelsize);
 147                else
 148                        labelsize = 128;
 149
 150                if (labelsize != sizeof_namespace_label(ndd)) {
 151                        dev_dbg(dev, "nsindex%d labelsize %d invalid\n",
 152                                        i, nsindex[i]->labelsize);
 153                        continue;
 154                }
 155
 156                sum_save = __le64_to_cpu(nsindex[i]->checksum);
 157                nsindex[i]->checksum = __cpu_to_le64(0);
 158                sum = nd_fletcher64(nsindex[i], sizeof_namespace_index(ndd), 1);
 159                nsindex[i]->checksum = __cpu_to_le64(sum_save);
 160                if (sum != sum_save) {
 161                        dev_dbg(dev, "nsindex%d checksum invalid\n", i);
 162                        continue;
 163                }
 164
 165                seq = __le32_to_cpu(nsindex[i]->seq);
 166                if ((seq & NSINDEX_SEQ_MASK) == 0) {
 167                        dev_dbg(dev, "nsindex%d sequence: %#x invalid\n", i, seq);
 168                        continue;
 169                }
 170
 171                /* sanity check the index against expected values */
 172                if (__le64_to_cpu(nsindex[i]->myoff)
 173                                != i * sizeof_namespace_index(ndd)) {
 174                        dev_dbg(dev, "nsindex%d myoff: %#llx invalid\n",
 175                                        i, (unsigned long long)
 176                                        __le64_to_cpu(nsindex[i]->myoff));
 177                        continue;
 178                }
 179                if (__le64_to_cpu(nsindex[i]->otheroff)
 180                                != (!i) * sizeof_namespace_index(ndd)) {
 181                        dev_dbg(dev, "nsindex%d otheroff: %#llx invalid\n",
 182                                        i, (unsigned long long)
 183                                        __le64_to_cpu(nsindex[i]->otheroff));
 184                        continue;
 185                }
 186
 187                size = __le64_to_cpu(nsindex[i]->mysize);
 188                if (size > sizeof_namespace_index(ndd)
 189                                || size < sizeof(struct nd_namespace_index)) {
 190                        dev_dbg(dev, "nsindex%d mysize: %#llx invalid\n", i, size);
 191                        continue;
 192                }
 193
 194                nslot = __le32_to_cpu(nsindex[i]->nslot);
 195                if (nslot * sizeof_namespace_label(ndd)
 196                                + 2 * sizeof_namespace_index(ndd)
 197                                > ndd->nsarea.config_size) {
 198                        dev_dbg(dev, "nsindex%d nslot: %u invalid, config_size: %#x\n",
 199                                        i, nslot, ndd->nsarea.config_size);
 200                        continue;
 201                }
 202                valid[i] = true;
 203                num_valid++;
 204        }
 205
 206        switch (num_valid) {
 207        case 0:
 208                break;
 209        case 1:
 210                for (i = 0; i < num_index; i++)
 211                        if (valid[i])
 212                                return i;
 213                /* can't have num_valid > 0 but valid[] = { false, false } */
 214                WARN_ON(1);
 215                break;
 216        default:
 217                /* pick the best index... */
 218                seq = best_seq(__le32_to_cpu(nsindex[0]->seq),
 219                                __le32_to_cpu(nsindex[1]->seq));
 220                if (seq == (__le32_to_cpu(nsindex[1]->seq) & NSINDEX_SEQ_MASK))
 221                        return 1;
 222                else
 223                        return 0;
 224                break;
 225        }
 226
 227        return -1;
 228}
 229
 230int nd_label_validate(struct nvdimm_drvdata *ndd)
 231{
 232        /*
 233         * In order to probe for and validate namespace index blocks we
 234         * need to know the size of the labels, and we can't trust the
 235         * size of the labels until we validate the index blocks.
 236         * Resolve this dependency loop by probing for known label
 237         * sizes, but default to v1.2 256-byte namespace labels if
 238         * discovery fails.
 239         */
 240        int label_size[] = { 128, 256 };
 241        int i, rc;
 242
 243        for (i = 0; i < ARRAY_SIZE(label_size); i++) {
 244                ndd->nslabel_size = label_size[i];
 245                rc = __nd_label_validate(ndd);
 246                if (rc >= 0)
 247                        return rc;
 248        }
 249
 250        return -1;
 251}
 252
 253void nd_label_copy(struct nvdimm_drvdata *ndd, struct nd_namespace_index *dst,
 254                struct nd_namespace_index *src)
 255{
 256        if (dst && src)
 257                /* pass */;
 258        else
 259                return;
 260
 261        memcpy(dst, src, sizeof_namespace_index(ndd));
 262}
 263
 264static struct nd_namespace_label *nd_label_base(struct nvdimm_drvdata *ndd)
 265{
 266        void *base = to_namespace_index(ndd, 0);
 267
 268        return base + 2 * sizeof_namespace_index(ndd);
 269}
 270
 271static int to_slot(struct nvdimm_drvdata *ndd,
 272                struct nd_namespace_label *nd_label)
 273{
 274        unsigned long label, base;
 275
 276        label = (unsigned long) nd_label;
 277        base = (unsigned long) nd_label_base(ndd);
 278
 279        return (label - base) / sizeof_namespace_label(ndd);
 280}
 281
 282static struct nd_namespace_label *to_label(struct nvdimm_drvdata *ndd, int slot)
 283{
 284        unsigned long label, base;
 285
 286        base = (unsigned long) nd_label_base(ndd);
 287        label = base + sizeof_namespace_label(ndd) * slot;
 288
 289        return (struct nd_namespace_label *) label;
 290}
 291
 292#define for_each_clear_bit_le(bit, addr, size) \
 293        for ((bit) = find_next_zero_bit_le((addr), (size), 0);  \
 294             (bit) < (size);                                    \
 295             (bit) = find_next_zero_bit_le((addr), (size), (bit) + 1))
 296
 297/**
 298 * preamble_index - common variable initialization for nd_label_* routines
 299 * @ndd: dimm container for the relevant label set
 300 * @idx: namespace_index index
 301 * @nsindex_out: on return set to the currently active namespace index
 302 * @free: on return set to the free label bitmap in the index
 303 * @nslot: on return set to the number of slots in the label space
 304 */
 305static bool preamble_index(struct nvdimm_drvdata *ndd, int idx,
 306                struct nd_namespace_index **nsindex_out,
 307                unsigned long **free, u32 *nslot)
 308{
 309        struct nd_namespace_index *nsindex;
 310
 311        nsindex = to_namespace_index(ndd, idx);
 312        if (nsindex == NULL)
 313                return false;
 314
 315        *free = (unsigned long *) nsindex->free;
 316        *nslot = __le32_to_cpu(nsindex->nslot);
 317        *nsindex_out = nsindex;
 318
 319        return true;
 320}
 321
 322char *nd_label_gen_id(struct nd_label_id *label_id, u8 *uuid, u32 flags)
 323{
 324        if (!label_id || !uuid)
 325                return NULL;
 326        snprintf(label_id->id, ND_LABEL_ID_SIZE, "%s-%pUb",
 327                        flags & NSLABEL_FLAG_LOCAL ? "blk" : "pmem", uuid);
 328        return label_id->id;
 329}
 330
 331static bool preamble_current(struct nvdimm_drvdata *ndd,
 332                struct nd_namespace_index **nsindex,
 333                unsigned long **free, u32 *nslot)
 334{
 335        return preamble_index(ndd, ndd->ns_current, nsindex,
 336                        free, nslot);
 337}
 338
 339static bool preamble_next(struct nvdimm_drvdata *ndd,
 340                struct nd_namespace_index **nsindex,
 341                unsigned long **free, u32 *nslot)
 342{
 343        return preamble_index(ndd, ndd->ns_next, nsindex,
 344                        free, nslot);
 345}
 346
 347static bool slot_valid(struct nvdimm_drvdata *ndd,
 348                struct nd_namespace_label *nd_label, u32 slot)
 349{
 350        /* check that we are written where we expect to be written */
 351        if (slot != __le32_to_cpu(nd_label->slot))
 352                return false;
 353
 354        /* check that DPA allocations are page aligned */
 355        if ((__le64_to_cpu(nd_label->dpa)
 356                                | __le64_to_cpu(nd_label->rawsize)) % SZ_4K)
 357                return false;
 358
 359        /* check checksum */
 360        if (namespace_label_has(ndd, checksum)) {
 361                u64 sum, sum_save;
 362
 363                sum_save = __le64_to_cpu(nd_label->checksum);
 364                nd_label->checksum = __cpu_to_le64(0);
 365                sum = nd_fletcher64(nd_label, sizeof_namespace_label(ndd), 1);
 366                nd_label->checksum = __cpu_to_le64(sum_save);
 367                if (sum != sum_save) {
 368                        dev_dbg(ndd->dev, "fail checksum. slot: %d expect: %#llx\n",
 369                                slot, sum);
 370                        return false;
 371                }
 372        }
 373
 374        return true;
 375}
 376
 377int nd_label_reserve_dpa(struct nvdimm_drvdata *ndd)
 378{
 379        struct nd_namespace_index *nsindex;
 380        unsigned long *free;
 381        u32 nslot, slot;
 382
 383        if (!preamble_current(ndd, &nsindex, &free, &nslot))
 384                return 0; /* no label, nothing to reserve */
 385
 386        for_each_clear_bit_le(slot, free, nslot) {
 387                struct nd_namespace_label *nd_label;
 388                struct nd_region *nd_region = NULL;
 389                u8 label_uuid[NSLABEL_UUID_LEN];
 390                struct nd_label_id label_id;
 391                struct resource *res;
 392                u32 flags;
 393
 394                nd_label = to_label(ndd, slot);
 395
 396                if (!slot_valid(ndd, nd_label, slot))
 397                        continue;
 398
 399                memcpy(label_uuid, nd_label->uuid, NSLABEL_UUID_LEN);
 400                flags = __le32_to_cpu(nd_label->flags);
 401                nd_label_gen_id(&label_id, label_uuid, flags);
 402                res = nvdimm_allocate_dpa(ndd, &label_id,
 403                                __le64_to_cpu(nd_label->dpa),
 404                                __le64_to_cpu(nd_label->rawsize));
 405                nd_dbg_dpa(nd_region, ndd, res, "reserve\n");
 406                if (!res)
 407                        return -EBUSY;
 408        }
 409
 410        return 0;
 411}
 412
 413int nd_label_active_count(struct nvdimm_drvdata *ndd)
 414{
 415        struct nd_namespace_index *nsindex;
 416        unsigned long *free;
 417        u32 nslot, slot;
 418        int count = 0;
 419
 420        if (!preamble_current(ndd, &nsindex, &free, &nslot))
 421                return 0;
 422
 423        for_each_clear_bit_le(slot, free, nslot) {
 424                struct nd_namespace_label *nd_label;
 425
 426                nd_label = to_label(ndd, slot);
 427
 428                if (!slot_valid(ndd, nd_label, slot)) {
 429                        u32 label_slot = __le32_to_cpu(nd_label->slot);
 430                        u64 size = __le64_to_cpu(nd_label->rawsize);
 431                        u64 dpa = __le64_to_cpu(nd_label->dpa);
 432
 433                        dev_dbg(ndd->dev,
 434                                "slot%d invalid slot: %d dpa: %llx size: %llx\n",
 435                                        slot, label_slot, dpa, size);
 436                        continue;
 437                }
 438                count++;
 439        }
 440        return count;
 441}
 442
 443struct nd_namespace_label *nd_label_active(struct nvdimm_drvdata *ndd, int n)
 444{
 445        struct nd_namespace_index *nsindex;
 446        unsigned long *free;
 447        u32 nslot, slot;
 448
 449        if (!preamble_current(ndd, &nsindex, &free, &nslot))
 450                return NULL;
 451
 452        for_each_clear_bit_le(slot, free, nslot) {
 453                struct nd_namespace_label *nd_label;
 454
 455                nd_label = to_label(ndd, slot);
 456                if (!slot_valid(ndd, nd_label, slot))
 457                        continue;
 458
 459                if (n-- == 0)
 460                        return to_label(ndd, slot);
 461        }
 462
 463        return NULL;
 464}
 465
 466u32 nd_label_alloc_slot(struct nvdimm_drvdata *ndd)
 467{
 468        struct nd_namespace_index *nsindex;
 469        unsigned long *free;
 470        u32 nslot, slot;
 471
 472        if (!preamble_next(ndd, &nsindex, &free, &nslot))
 473                return UINT_MAX;
 474
 475        WARN_ON(!is_nvdimm_bus_locked(ndd->dev));
 476
 477        slot = find_next_bit_le(free, nslot, 0);
 478        if (slot == nslot)
 479                return UINT_MAX;
 480
 481        clear_bit_le(slot, free);
 482
 483        return slot;
 484}
 485
 486bool nd_label_free_slot(struct nvdimm_drvdata *ndd, u32 slot)
 487{
 488        struct nd_namespace_index *nsindex;
 489        unsigned long *free;
 490        u32 nslot;
 491
 492        if (!preamble_next(ndd, &nsindex, &free, &nslot))
 493                return false;
 494
 495        WARN_ON(!is_nvdimm_bus_locked(ndd->dev));
 496
 497        if (slot < nslot)
 498                return !test_and_set_bit_le(slot, free);
 499        return false;
 500}
 501
 502u32 nd_label_nfree(struct nvdimm_drvdata *ndd)
 503{
 504        struct nd_namespace_index *nsindex;
 505        unsigned long *free;
 506        u32 nslot;
 507
 508        WARN_ON(!is_nvdimm_bus_locked(ndd->dev));
 509
 510        if (!preamble_next(ndd, &nsindex, &free, &nslot))
 511                return nvdimm_num_label_slots(ndd);
 512
 513        return bitmap_weight(free, nslot);
 514}
 515
 516static int nd_label_write_index(struct nvdimm_drvdata *ndd, int index, u32 seq,
 517                unsigned long flags)
 518{
 519        struct nd_namespace_index *nsindex;
 520        unsigned long offset;
 521        u64 checksum;
 522        u32 nslot;
 523        int rc;
 524
 525        nsindex = to_namespace_index(ndd, index);
 526        if (flags & ND_NSINDEX_INIT)
 527                nslot = nvdimm_num_label_slots(ndd);
 528        else
 529                nslot = __le32_to_cpu(nsindex->nslot);
 530
 531        memcpy(nsindex->sig, NSINDEX_SIGNATURE, NSINDEX_SIG_LEN);
 532        memset(&nsindex->flags, 0, 3);
 533        nsindex->labelsize = sizeof_namespace_label(ndd) >> 8;
 534        nsindex->seq = __cpu_to_le32(seq);
 535        offset = (unsigned long) nsindex
 536                - (unsigned long) to_namespace_index(ndd, 0);
 537        nsindex->myoff = __cpu_to_le64(offset);
 538        nsindex->mysize = __cpu_to_le64(sizeof_namespace_index(ndd));
 539        offset = (unsigned long) to_namespace_index(ndd,
 540                        nd_label_next_nsindex(index))
 541                - (unsigned long) to_namespace_index(ndd, 0);
 542        nsindex->otheroff = __cpu_to_le64(offset);
 543        offset = (unsigned long) nd_label_base(ndd)
 544                - (unsigned long) to_namespace_index(ndd, 0);
 545        nsindex->labeloff = __cpu_to_le64(offset);
 546        nsindex->nslot = __cpu_to_le32(nslot);
 547        nsindex->major = __cpu_to_le16(1);
 548        if (sizeof_namespace_label(ndd) < 256)
 549                nsindex->minor = __cpu_to_le16(1);
 550        else
 551                nsindex->minor = __cpu_to_le16(2);
 552        nsindex->checksum = __cpu_to_le64(0);
 553        if (flags & ND_NSINDEX_INIT) {
 554                unsigned long *free = (unsigned long *) nsindex->free;
 555                u32 nfree = ALIGN(nslot, BITS_PER_LONG);
 556                int last_bits, i;
 557
 558                memset(nsindex->free, 0xff, nfree / 8);
 559                for (i = 0, last_bits = nfree - nslot; i < last_bits; i++)
 560                        clear_bit_le(nslot + i, free);
 561        }
 562        checksum = nd_fletcher64(nsindex, sizeof_namespace_index(ndd), 1);
 563        nsindex->checksum = __cpu_to_le64(checksum);
 564        rc = nvdimm_set_config_data(ndd, __le64_to_cpu(nsindex->myoff),
 565                        nsindex, sizeof_namespace_index(ndd));
 566        if (rc < 0)
 567                return rc;
 568
 569        if (flags & ND_NSINDEX_INIT)
 570                return 0;
 571
 572        /* copy the index we just wrote to the new 'next' */
 573        WARN_ON(index != ndd->ns_next);
 574        nd_label_copy(ndd, to_current_namespace_index(ndd), nsindex);
 575        ndd->ns_current = nd_label_next_nsindex(ndd->ns_current);
 576        ndd->ns_next = nd_label_next_nsindex(ndd->ns_next);
 577        WARN_ON(ndd->ns_current == ndd->ns_next);
 578
 579        return 0;
 580}
 581
 582static unsigned long nd_label_offset(struct nvdimm_drvdata *ndd,
 583                struct nd_namespace_label *nd_label)
 584{
 585        return (unsigned long) nd_label
 586                - (unsigned long) to_namespace_index(ndd, 0);
 587}
 588
 589enum nvdimm_claim_class to_nvdimm_cclass(guid_t *guid)
 590{
 591        if (guid_equal(guid, &nvdimm_btt_guid))
 592                return NVDIMM_CCLASS_BTT;
 593        else if (guid_equal(guid, &nvdimm_btt2_guid))
 594                return NVDIMM_CCLASS_BTT2;
 595        else if (guid_equal(guid, &nvdimm_pfn_guid))
 596                return NVDIMM_CCLASS_PFN;
 597        else if (guid_equal(guid, &nvdimm_dax_guid))
 598                return NVDIMM_CCLASS_DAX;
 599        else if (guid_equal(guid, &guid_null))
 600                return NVDIMM_CCLASS_NONE;
 601
 602        return NVDIMM_CCLASS_UNKNOWN;
 603}
 604
 605static const guid_t *to_abstraction_guid(enum nvdimm_claim_class claim_class,
 606        guid_t *target)
 607{
 608        if (claim_class == NVDIMM_CCLASS_BTT)
 609                return &nvdimm_btt_guid;
 610        else if (claim_class == NVDIMM_CCLASS_BTT2)
 611                return &nvdimm_btt2_guid;
 612        else if (claim_class == NVDIMM_CCLASS_PFN)
 613                return &nvdimm_pfn_guid;
 614        else if (claim_class == NVDIMM_CCLASS_DAX)
 615                return &nvdimm_dax_guid;
 616        else if (claim_class == NVDIMM_CCLASS_UNKNOWN) {
 617                /*
 618                 * If we're modifying a namespace for which we don't
 619                 * know the claim_class, don't touch the existing guid.
 620                 */
 621                return target;
 622        } else
 623                return &guid_null;
 624}
 625
 626static int __pmem_label_update(struct nd_region *nd_region,
 627                struct nd_mapping *nd_mapping, struct nd_namespace_pmem *nspm,
 628                int pos)
 629{
 630        struct nd_namespace_common *ndns = &nspm->nsio.common;
 631        struct nd_interleave_set *nd_set = nd_region->nd_set;
 632        struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
 633        struct nd_label_ent *label_ent, *victim = NULL;
 634        struct nd_namespace_label *nd_label;
 635        struct nd_namespace_index *nsindex;
 636        struct nd_label_id label_id;
 637        struct resource *res;
 638        unsigned long *free;
 639        u32 nslot, slot;
 640        size_t offset;
 641        u64 cookie;
 642        int rc;
 643
 644        if (!preamble_next(ndd, &nsindex, &free, &nslot))
 645                return -ENXIO;
 646
 647        cookie = nd_region_interleave_set_cookie(nd_region, nsindex);
 648        nd_label_gen_id(&label_id, nspm->uuid, 0);
 649        for_each_dpa_resource(ndd, res)
 650                if (strcmp(res->name, label_id.id) == 0)
 651                        break;
 652
 653        if (!res) {
 654                WARN_ON_ONCE(1);
 655                return -ENXIO;
 656        }
 657
 658        /* allocate and write the label to the staging (next) index */
 659        slot = nd_label_alloc_slot(ndd);
 660        if (slot == UINT_MAX)
 661                return -ENXIO;
 662        dev_dbg(ndd->dev, "allocated: %d\n", slot);
 663
 664        nd_label = to_label(ndd, slot);
 665        memset(nd_label, 0, sizeof_namespace_label(ndd));
 666        memcpy(nd_label->uuid, nspm->uuid, NSLABEL_UUID_LEN);
 667        if (nspm->alt_name)
 668                memcpy(nd_label->name, nspm->alt_name, NSLABEL_NAME_LEN);
 669        nd_label->flags = __cpu_to_le32(NSLABEL_FLAG_UPDATING);
 670        nd_label->nlabel = __cpu_to_le16(nd_region->ndr_mappings);
 671        nd_label->position = __cpu_to_le16(pos);
 672        nd_label->isetcookie = __cpu_to_le64(cookie);
 673        nd_label->rawsize = __cpu_to_le64(resource_size(res));
 674        nd_label->lbasize = __cpu_to_le64(nspm->lbasize);
 675        nd_label->dpa = __cpu_to_le64(res->start);
 676        nd_label->slot = __cpu_to_le32(slot);
 677        if (namespace_label_has(ndd, type_guid))
 678                guid_copy(&nd_label->type_guid, &nd_set->type_guid);
 679        if (namespace_label_has(ndd, abstraction_guid))
 680                guid_copy(&nd_label->abstraction_guid,
 681                                to_abstraction_guid(ndns->claim_class,
 682                                        &nd_label->abstraction_guid));
 683        if (namespace_label_has(ndd, checksum)) {
 684                u64 sum;
 685
 686                nd_label->checksum = __cpu_to_le64(0);
 687                sum = nd_fletcher64(nd_label, sizeof_namespace_label(ndd), 1);
 688                nd_label->checksum = __cpu_to_le64(sum);
 689        }
 690        nd_dbg_dpa(nd_region, ndd, res, "\n");
 691
 692        /* update label */
 693        offset = nd_label_offset(ndd, nd_label);
 694        rc = nvdimm_set_config_data(ndd, offset, nd_label,
 695                        sizeof_namespace_label(ndd));
 696        if (rc < 0)
 697                return rc;
 698
 699        /* Garbage collect the previous label */
 700        mutex_lock(&nd_mapping->lock);
 701        list_for_each_entry(label_ent, &nd_mapping->labels, list) {
 702                if (!label_ent->label)
 703                        continue;
 704                if (memcmp(nspm->uuid, label_ent->label->uuid,
 705                                        NSLABEL_UUID_LEN) != 0)
 706                        continue;
 707                victim = label_ent;
 708                list_move_tail(&victim->list, &nd_mapping->labels);
 709                break;
 710        }
 711        if (victim) {
 712                dev_dbg(ndd->dev, "free: %d\n", slot);
 713                slot = to_slot(ndd, victim->label);
 714                nd_label_free_slot(ndd, slot);
 715                victim->label = NULL;
 716        }
 717
 718        /* update index */
 719        rc = nd_label_write_index(ndd, ndd->ns_next,
 720                        nd_inc_seq(__le32_to_cpu(nsindex->seq)), 0);
 721        if (rc == 0) {
 722                list_for_each_entry(label_ent, &nd_mapping->labels, list)
 723                        if (!label_ent->label) {
 724                                label_ent->label = nd_label;
 725                                nd_label = NULL;
 726                                break;
 727                        }
 728                dev_WARN_ONCE(&nspm->nsio.common.dev, nd_label,
 729                                "failed to track label: %d\n",
 730                                to_slot(ndd, nd_label));
 731                if (nd_label)
 732                        rc = -ENXIO;
 733        }
 734        mutex_unlock(&nd_mapping->lock);
 735
 736        return rc;
 737}
 738
 739static bool is_old_resource(struct resource *res, struct resource **list, int n)
 740{
 741        int i;
 742
 743        if (res->flags & DPA_RESOURCE_ADJUSTED)
 744                return false;
 745        for (i = 0; i < n; i++)
 746                if (res == list[i])
 747                        return true;
 748        return false;
 749}
 750
 751static struct resource *to_resource(struct nvdimm_drvdata *ndd,
 752                struct nd_namespace_label *nd_label)
 753{
 754        struct resource *res;
 755
 756        for_each_dpa_resource(ndd, res) {
 757                if (res->start != __le64_to_cpu(nd_label->dpa))
 758                        continue;
 759                if (resource_size(res) != __le64_to_cpu(nd_label->rawsize))
 760                        continue;
 761                return res;
 762        }
 763
 764        return NULL;
 765}
 766
 767/*
 768 * 1/ Account all the labels that can be freed after this update
 769 * 2/ Allocate and write the label to the staging (next) index
 770 * 3/ Record the resources in the namespace device
 771 */
 772static int __blk_label_update(struct nd_region *nd_region,
 773                struct nd_mapping *nd_mapping, struct nd_namespace_blk *nsblk,
 774                int num_labels)
 775{
 776        int i, alloc, victims, nfree, old_num_resources, nlabel, rc = -ENXIO;
 777        struct nd_interleave_set *nd_set = nd_region->nd_set;
 778        struct nd_namespace_common *ndns = &nsblk->common;
 779        struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
 780        struct nd_namespace_label *nd_label;
 781        struct nd_label_ent *label_ent, *e;
 782        struct nd_namespace_index *nsindex;
 783        unsigned long *free, *victim_map = NULL;
 784        struct resource *res, **old_res_list;
 785        struct nd_label_id label_id;
 786        u8 uuid[NSLABEL_UUID_LEN];
 787        int min_dpa_idx = 0;
 788        LIST_HEAD(list);
 789        u32 nslot, slot;
 790
 791        if (!preamble_next(ndd, &nsindex, &free, &nslot))
 792                return -ENXIO;
 793
 794        old_res_list = nsblk->res;
 795        nfree = nd_label_nfree(ndd);
 796        old_num_resources = nsblk->num_resources;
 797        nd_label_gen_id(&label_id, nsblk->uuid, NSLABEL_FLAG_LOCAL);
 798
 799        /*
 800         * We need to loop over the old resources a few times, which seems a
 801         * bit inefficient, but we need to know that we have the label
 802         * space before we start mutating the tracking structures.
 803         * Otherwise the recovery method of last resort for userspace is
 804         * disable and re-enable the parent region.
 805         */
 806        alloc = 0;
 807        for_each_dpa_resource(ndd, res) {
 808                if (strcmp(res->name, label_id.id) != 0)
 809                        continue;
 810                if (!is_old_resource(res, old_res_list, old_num_resources))
 811                        alloc++;
 812        }
 813
 814        victims = 0;
 815        if (old_num_resources) {
 816                /* convert old local-label-map to dimm-slot victim-map */
 817                victim_map = kcalloc(BITS_TO_LONGS(nslot), sizeof(long),
 818                                GFP_KERNEL);
 819                if (!victim_map)
 820                        return -ENOMEM;
 821
 822                /* mark unused labels for garbage collection */
 823                for_each_clear_bit_le(slot, free, nslot) {
 824                        nd_label = to_label(ndd, slot);
 825                        memcpy(uuid, nd_label->uuid, NSLABEL_UUID_LEN);
 826                        if (memcmp(uuid, nsblk->uuid, NSLABEL_UUID_LEN) != 0)
 827                                continue;
 828                        res = to_resource(ndd, nd_label);
 829                        if (res && is_old_resource(res, old_res_list,
 830                                                old_num_resources))
 831                                continue;
 832                        slot = to_slot(ndd, nd_label);
 833                        set_bit(slot, victim_map);
 834                        victims++;
 835                }
 836        }
 837
 838        /* don't allow updates that consume the last label */
 839        if (nfree - alloc < 0 || nfree - alloc + victims < 1) {
 840                dev_info(&nsblk->common.dev, "insufficient label space\n");
 841                kfree(victim_map);
 842                return -ENOSPC;
 843        }
 844        /* from here on we need to abort on error */
 845
 846
 847        /* assign all resources to the namespace before writing the labels */
 848        nsblk->res = NULL;
 849        nsblk->num_resources = 0;
 850        for_each_dpa_resource(ndd, res) {
 851                if (strcmp(res->name, label_id.id) != 0)
 852                        continue;
 853                if (!nsblk_add_resource(nd_region, ndd, nsblk, res->start)) {
 854                        rc = -ENOMEM;
 855                        goto abort;
 856                }
 857        }
 858
 859        /*
 860         * Find the resource associated with the first label in the set
 861         * per the v1.2 namespace specification.
 862         */
 863        for (i = 0; i < nsblk->num_resources; i++) {
 864                struct resource *min = nsblk->res[min_dpa_idx];
 865
 866                res = nsblk->res[i];
 867                if (res->start < min->start)
 868                        min_dpa_idx = i;
 869        }
 870
 871        for (i = 0; i < nsblk->num_resources; i++) {
 872                size_t offset;
 873
 874                res = nsblk->res[i];
 875                if (is_old_resource(res, old_res_list, old_num_resources))
 876                        continue; /* carry-over */
 877                slot = nd_label_alloc_slot(ndd);
 878                if (slot == UINT_MAX)
 879                        goto abort;
 880                dev_dbg(ndd->dev, "allocated: %d\n", slot);
 881
 882                nd_label = to_label(ndd, slot);
 883                memset(nd_label, 0, sizeof_namespace_label(ndd));
 884                memcpy(nd_label->uuid, nsblk->uuid, NSLABEL_UUID_LEN);
 885                if (nsblk->alt_name)
 886                        memcpy(nd_label->name, nsblk->alt_name,
 887                                        NSLABEL_NAME_LEN);
 888                nd_label->flags = __cpu_to_le32(NSLABEL_FLAG_LOCAL);
 889
 890                /*
 891                 * Use the presence of the type_guid as a flag to
 892                 * determine isetcookie usage and nlabel + position
 893                 * policy for blk-aperture namespaces.
 894                 */
 895                if (namespace_label_has(ndd, type_guid)) {
 896                        if (i == min_dpa_idx) {
 897                                nd_label->nlabel = __cpu_to_le16(nsblk->num_resources);
 898                                nd_label->position = __cpu_to_le16(0);
 899                        } else {
 900                                nd_label->nlabel = __cpu_to_le16(0xffff);
 901                                nd_label->position = __cpu_to_le16(0xffff);
 902                        }
 903                        nd_label->isetcookie = __cpu_to_le64(nd_set->cookie2);
 904                } else {
 905                        nd_label->nlabel = __cpu_to_le16(0); /* N/A */
 906                        nd_label->position = __cpu_to_le16(0); /* N/A */
 907                        nd_label->isetcookie = __cpu_to_le64(0); /* N/A */
 908                }
 909
 910                nd_label->dpa = __cpu_to_le64(res->start);
 911                nd_label->rawsize = __cpu_to_le64(resource_size(res));
 912                nd_label->lbasize = __cpu_to_le64(nsblk->lbasize);
 913                nd_label->slot = __cpu_to_le32(slot);
 914                if (namespace_label_has(ndd, type_guid))
 915                        guid_copy(&nd_label->type_guid, &nd_set->type_guid);
 916                if (namespace_label_has(ndd, abstraction_guid))
 917                        guid_copy(&nd_label->abstraction_guid,
 918                                        to_abstraction_guid(ndns->claim_class,
 919                                                &nd_label->abstraction_guid));
 920
 921                if (namespace_label_has(ndd, checksum)) {
 922                        u64 sum;
 923
 924                        nd_label->checksum = __cpu_to_le64(0);
 925                        sum = nd_fletcher64(nd_label,
 926                                        sizeof_namespace_label(ndd), 1);
 927                        nd_label->checksum = __cpu_to_le64(sum);
 928                }
 929
 930                /* update label */
 931                offset = nd_label_offset(ndd, nd_label);
 932                rc = nvdimm_set_config_data(ndd, offset, nd_label,
 933                                sizeof_namespace_label(ndd));
 934                if (rc < 0)
 935                        goto abort;
 936        }
 937
 938        /* free up now unused slots in the new index */
 939        for_each_set_bit(slot, victim_map, victim_map ? nslot : 0) {
 940                dev_dbg(ndd->dev, "free: %d\n", slot);
 941                nd_label_free_slot(ndd, slot);
 942        }
 943
 944        /* update index */
 945        rc = nd_label_write_index(ndd, ndd->ns_next,
 946                        nd_inc_seq(__le32_to_cpu(nsindex->seq)), 0);
 947        if (rc)
 948                goto abort;
 949
 950        /*
 951         * Now that the on-dimm labels are up to date, fix up the tracking
 952         * entries in nd_mapping->labels
 953         */
 954        nlabel = 0;
 955        mutex_lock(&nd_mapping->lock);
 956        list_for_each_entry_safe(label_ent, e, &nd_mapping->labels, list) {
 957                nd_label = label_ent->label;
 958                if (!nd_label)
 959                        continue;
 960                nlabel++;
 961                memcpy(uuid, nd_label->uuid, NSLABEL_UUID_LEN);
 962                if (memcmp(uuid, nsblk->uuid, NSLABEL_UUID_LEN) != 0)
 963                        continue;
 964                nlabel--;
 965                list_move(&label_ent->list, &list);
 966                label_ent->label = NULL;
 967        }
 968        list_splice_tail_init(&list, &nd_mapping->labels);
 969        mutex_unlock(&nd_mapping->lock);
 970
 971        if (nlabel + nsblk->num_resources > num_labels) {
 972                /*
 973                 * Bug, we can't end up with more resources than
 974                 * available labels
 975                 */
 976                WARN_ON_ONCE(1);
 977                rc = -ENXIO;
 978                goto out;
 979        }
 980
 981        mutex_lock(&nd_mapping->lock);
 982        label_ent = list_first_entry_or_null(&nd_mapping->labels,
 983                        typeof(*label_ent), list);
 984        if (!label_ent) {
 985                WARN_ON(1);
 986                mutex_unlock(&nd_mapping->lock);
 987                rc = -ENXIO;
 988                goto out;
 989        }
 990        for_each_clear_bit_le(slot, free, nslot) {
 991                nd_label = to_label(ndd, slot);
 992                memcpy(uuid, nd_label->uuid, NSLABEL_UUID_LEN);
 993                if (memcmp(uuid, nsblk->uuid, NSLABEL_UUID_LEN) != 0)
 994                        continue;
 995                res = to_resource(ndd, nd_label);
 996                res->flags &= ~DPA_RESOURCE_ADJUSTED;
 997                dev_vdbg(&nsblk->common.dev, "assign label slot: %d\n", slot);
 998                list_for_each_entry_from(label_ent, &nd_mapping->labels, list) {
 999                        if (label_ent->label)
1000                                continue;
1001                        label_ent->label = nd_label;
1002                        nd_label = NULL;
1003                        break;
1004                }
1005                if (nd_label)
1006                        dev_WARN(&nsblk->common.dev,
1007                                        "failed to track label slot%d\n", slot);
1008        }
1009        mutex_unlock(&nd_mapping->lock);
1010
1011 out:
1012        kfree(old_res_list);
1013        kfree(victim_map);
1014        return rc;
1015
1016 abort:
1017        /*
1018         * 1/ repair the allocated label bitmap in the index
1019         * 2/ restore the resource list
1020         */
1021        nd_label_copy(ndd, nsindex, to_current_namespace_index(ndd));
1022        kfree(nsblk->res);
1023        nsblk->res = old_res_list;
1024        nsblk->num_resources = old_num_resources;
1025        old_res_list = NULL;
1026        goto out;
1027}
1028
1029static int init_labels(struct nd_mapping *nd_mapping, int num_labels)
1030{
1031        int i, old_num_labels = 0;
1032        struct nd_label_ent *label_ent;
1033        struct nd_namespace_index *nsindex;
1034        struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
1035
1036        mutex_lock(&nd_mapping->lock);
1037        list_for_each_entry(label_ent, &nd_mapping->labels, list)
1038                old_num_labels++;
1039        mutex_unlock(&nd_mapping->lock);
1040
1041        /*
1042         * We need to preserve all the old labels for the mapping so
1043         * they can be garbage collected after writing the new labels.
1044         */
1045        for (i = old_num_labels; i < num_labels; i++) {
1046                label_ent = kzalloc(sizeof(*label_ent), GFP_KERNEL);
1047                if (!label_ent)
1048                        return -ENOMEM;
1049                mutex_lock(&nd_mapping->lock);
1050                list_add_tail(&label_ent->list, &nd_mapping->labels);
1051                mutex_unlock(&nd_mapping->lock);
1052        }
1053
1054        if (ndd->ns_current == -1 || ndd->ns_next == -1)
1055                /* pass */;
1056        else
1057                return max(num_labels, old_num_labels);
1058
1059        nsindex = to_namespace_index(ndd, 0);
1060        memset(nsindex, 0, ndd->nsarea.config_size);
1061        for (i = 0; i < 2; i++) {
1062                int rc = nd_label_write_index(ndd, i, 3 - i, ND_NSINDEX_INIT);
1063
1064                if (rc)
1065                        return rc;
1066        }
1067        ndd->ns_next = 1;
1068        ndd->ns_current = 0;
1069
1070        return max(num_labels, old_num_labels);
1071}
1072
1073static int del_labels(struct nd_mapping *nd_mapping, u8 *uuid)
1074{
1075        struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
1076        struct nd_label_ent *label_ent, *e;
1077        struct nd_namespace_index *nsindex;
1078        u8 label_uuid[NSLABEL_UUID_LEN];
1079        unsigned long *free;
1080        LIST_HEAD(list);
1081        u32 nslot, slot;
1082        int active = 0;
1083
1084        if (!uuid)
1085                return 0;
1086
1087        /* no index || no labels == nothing to delete */
1088        if (!preamble_next(ndd, &nsindex, &free, &nslot))
1089                return 0;
1090
1091        mutex_lock(&nd_mapping->lock);
1092        list_for_each_entry_safe(label_ent, e, &nd_mapping->labels, list) {
1093                struct nd_namespace_label *nd_label = label_ent->label;
1094
1095                if (!nd_label)
1096                        continue;
1097                active++;
1098                memcpy(label_uuid, nd_label->uuid, NSLABEL_UUID_LEN);
1099                if (memcmp(label_uuid, uuid, NSLABEL_UUID_LEN) != 0)
1100                        continue;
1101                active--;
1102                slot = to_slot(ndd, nd_label);
1103                nd_label_free_slot(ndd, slot);
1104                dev_dbg(ndd->dev, "free: %d\n", slot);
1105                list_move_tail(&label_ent->list, &list);
1106                label_ent->label = NULL;
1107        }
1108        list_splice_tail_init(&list, &nd_mapping->labels);
1109
1110        if (active == 0) {
1111                nd_mapping_free_labels(nd_mapping);
1112                dev_dbg(ndd->dev, "no more active labels\n");
1113        }
1114        mutex_unlock(&nd_mapping->lock);
1115
1116        return nd_label_write_index(ndd, ndd->ns_next,
1117                        nd_inc_seq(__le32_to_cpu(nsindex->seq)), 0);
1118}
1119
1120int nd_pmem_namespace_label_update(struct nd_region *nd_region,
1121                struct nd_namespace_pmem *nspm, resource_size_t size)
1122{
1123        int i;
1124
1125        for (i = 0; i < nd_region->ndr_mappings; i++) {
1126                struct nd_mapping *nd_mapping = &nd_region->mapping[i];
1127                struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
1128                struct resource *res;
1129                int rc, count = 0;
1130
1131                if (size == 0) {
1132                        rc = del_labels(nd_mapping, nspm->uuid);
1133                        if (rc)
1134                                return rc;
1135                        continue;
1136                }
1137
1138                for_each_dpa_resource(ndd, res)
1139                        if (strncmp(res->name, "pmem", 4) == 0)
1140                                count++;
1141                WARN_ON_ONCE(!count);
1142
1143                rc = init_labels(nd_mapping, count);
1144                if (rc < 0)
1145                        return rc;
1146
1147                rc = __pmem_label_update(nd_region, nd_mapping, nspm, i);
1148                if (rc)
1149                        return rc;
1150        }
1151
1152        return 0;
1153}
1154
1155int nd_blk_namespace_label_update(struct nd_region *nd_region,
1156                struct nd_namespace_blk *nsblk, resource_size_t size)
1157{
1158        struct nd_mapping *nd_mapping = &nd_region->mapping[0];
1159        struct resource *res;
1160        int count = 0;
1161
1162        if (size == 0)
1163                return del_labels(nd_mapping, nsblk->uuid);
1164
1165        for_each_dpa_resource(to_ndd(nd_mapping), res)
1166                count++;
1167
1168        count = init_labels(nd_mapping, count);
1169        if (count < 0)
1170                return count;
1171
1172        return __blk_label_update(nd_region, nd_mapping, nsblk, count);
1173}
1174
1175int __init nd_label_init(void)
1176{
1177        WARN_ON(guid_parse(NVDIMM_BTT_GUID, &nvdimm_btt_guid));
1178        WARN_ON(guid_parse(NVDIMM_BTT2_GUID, &nvdimm_btt2_guid));
1179        WARN_ON(guid_parse(NVDIMM_PFN_GUID, &nvdimm_pfn_guid));
1180        WARN_ON(guid_parse(NVDIMM_DAX_GUID, &nvdimm_dax_guid));
1181
1182        return 0;
1183}
1184