Merge tag 'io_uring-5.15-2021-09-11' of git://git.kernel.dk/linux-block
[linux-2.6-microblaze.git] / drivers / nvdimm / label.c
index b40a4ed..7f473f9 100644 (file)
@@ -346,29 +346,45 @@ static bool preamble_next(struct nvdimm_drvdata *ndd,
                        free, nslot);
 }
 
+static bool nsl_validate_checksum(struct nvdimm_drvdata *ndd,
+                                 struct nd_namespace_label *nd_label)
+{
+       u64 sum, sum_save;
+
+       if (!namespace_label_has(ndd, checksum))
+               return true;
+
+       sum_save = nsl_get_checksum(ndd, nd_label);
+       nsl_set_checksum(ndd, nd_label, 0);
+       sum = nd_fletcher64(nd_label, sizeof_namespace_label(ndd), 1);
+       nsl_set_checksum(ndd, nd_label, sum_save);
+       return sum == sum_save;
+}
+
+static void nsl_calculate_checksum(struct nvdimm_drvdata *ndd,
+                                  struct nd_namespace_label *nd_label)
+{
+       u64 sum;
+
+       if (!namespace_label_has(ndd, checksum))
+               return;
+       nsl_set_checksum(ndd, nd_label, 0);
+       sum = nd_fletcher64(nd_label, sizeof_namespace_label(ndd), 1);
+       nsl_set_checksum(ndd, nd_label, sum);
+}
+
 static bool slot_valid(struct nvdimm_drvdata *ndd,
                struct nd_namespace_label *nd_label, u32 slot)
 {
+       bool valid;
+
        /* check that we are written where we expect to be written */
        if (slot != nsl_get_slot(ndd, nd_label))
                return false;
-
-       /* check checksum */
-       if (namespace_label_has(ndd, checksum)) {
-               u64 sum, sum_save;
-
-               sum_save = nsl_get_checksum(ndd, nd_label);
-               nsl_set_checksum(ndd, nd_label, 0);
-               sum = nd_fletcher64(nd_label, sizeof_namespace_label(ndd), 1);
-               nsl_set_checksum(ndd, nd_label, sum_save);
-               if (sum != sum_save) {
-                       dev_dbg(ndd->dev, "fail checksum. slot: %d expect: %#llx\n",
-                               slot, sum);
-                       return false;
-               }
-       }
-
-       return true;
+       valid = nsl_validate_checksum(ndd, nd_label);
+       if (!valid)
+               dev_dbg(ndd->dev, "fail checksum. slot: %d\n", slot);
+       return valid;
 }
 
 int nd_label_reserve_dpa(struct nvdimm_drvdata *ndd)
@@ -708,7 +724,7 @@ static unsigned long nd_label_offset(struct nvdimm_drvdata *ndd,
                - (unsigned long) to_namespace_index(ndd, 0);
 }
 
-enum nvdimm_claim_class to_nvdimm_cclass(guid_t *guid)
+static enum nvdimm_claim_class to_nvdimm_cclass(guid_t *guid)
 {
        if (guid_equal(guid, &nvdimm_btt_guid))
                return NVDIMM_CCLASS_BTT;
@@ -756,6 +772,45 @@ static void reap_victim(struct nd_mapping *nd_mapping,
        victim->label = NULL;
 }
 
+static void nsl_set_type_guid(struct nvdimm_drvdata *ndd,
+                             struct nd_namespace_label *nd_label, guid_t *guid)
+{
+       if (namespace_label_has(ndd, type_guid))
+               guid_copy(&nd_label->type_guid, guid);
+}
+
+bool nsl_validate_type_guid(struct nvdimm_drvdata *ndd,
+                           struct nd_namespace_label *nd_label, guid_t *guid)
+{
+       if (!namespace_label_has(ndd, type_guid))
+               return true;
+       if (!guid_equal(&nd_label->type_guid, guid)) {
+               dev_dbg(ndd->dev, "expect type_guid %pUb got %pUb\n", guid,
+                       &nd_label->type_guid);
+               return false;
+       }
+       return true;
+}
+
+static void nsl_set_claim_class(struct nvdimm_drvdata *ndd,
+                               struct nd_namespace_label *nd_label,
+                               enum nvdimm_claim_class claim_class)
+{
+       if (!namespace_label_has(ndd, abstraction_guid))
+               return;
+       guid_copy(&nd_label->abstraction_guid,
+                 to_abstraction_guid(claim_class,
+                                     &nd_label->abstraction_guid));
+}
+
+enum nvdimm_claim_class nsl_get_claim_class(struct nvdimm_drvdata *ndd,
+                                           struct nd_namespace_label *nd_label)
+{
+       if (!namespace_label_has(ndd, abstraction_guid))
+               return NVDIMM_CCLASS_NONE;
+       return to_nvdimm_cclass(&nd_label->abstraction_guid);
+}
+
 static int __pmem_label_update(struct nd_region *nd_region,
                struct nd_mapping *nd_mapping, struct nd_namespace_pmem *nspm,
                int pos, unsigned long flags)
@@ -806,19 +861,9 @@ static int __pmem_label_update(struct nd_region *nd_region,
        nsl_set_lbasize(ndd, nd_label, nspm->lbasize);
        nsl_set_dpa(ndd, nd_label, res->start);
        nsl_set_slot(ndd, nd_label, slot);
-       if (namespace_label_has(ndd, type_guid))
-               guid_copy(&nd_label->type_guid, &nd_set->type_guid);
-       if (namespace_label_has(ndd, abstraction_guid))
-               guid_copy(&nd_label->abstraction_guid,
-                               to_abstraction_guid(ndns->claim_class,
-                                       &nd_label->abstraction_guid));
-       if (namespace_label_has(ndd, checksum)) {
-               u64 sum;
-
-               nsl_set_checksum(ndd, nd_label, 0);
-               sum = nd_fletcher64(nd_label, sizeof_namespace_label(ndd), 1);
-               nsl_set_checksum(ndd, nd_label, sum);
-       }
+       nsl_set_type_guid(ndd, nd_label, &nd_set->type_guid);
+       nsl_set_claim_class(ndd, nd_label, ndns->claim_class);
+       nsl_calculate_checksum(ndd, nd_label);
        nd_dbg_dpa(nd_region, ndd, res, "\n");
 
        /* update label */
@@ -888,6 +933,59 @@ static struct resource *to_resource(struct nvdimm_drvdata *ndd,
        return NULL;
 }
 
+/*
+ * Use the presence of the type_guid as a flag to determine isetcookie
+ * usage and nlabel + position policy for blk-aperture namespaces.
+ */
+static void nsl_set_blk_isetcookie(struct nvdimm_drvdata *ndd,
+                                  struct nd_namespace_label *nd_label,
+                                  u64 isetcookie)
+{
+       if (namespace_label_has(ndd, type_guid)) {
+               nsl_set_isetcookie(ndd, nd_label, isetcookie);
+               return;
+       }
+       nsl_set_isetcookie(ndd, nd_label, 0); /* N/A */
+}
+
+bool nsl_validate_blk_isetcookie(struct nvdimm_drvdata *ndd,
+                                struct nd_namespace_label *nd_label,
+                                u64 isetcookie)
+{
+       if (!namespace_label_has(ndd, type_guid))
+               return true;
+
+       if (nsl_get_isetcookie(ndd, nd_label) != isetcookie) {
+               dev_dbg(ndd->dev, "expect cookie %#llx got %#llx\n", isetcookie,
+                       nsl_get_isetcookie(ndd, nd_label));
+               return false;
+       }
+
+       return true;
+}
+
+static void nsl_set_blk_nlabel(struct nvdimm_drvdata *ndd,
+                              struct nd_namespace_label *nd_label, int nlabel,
+                              bool first)
+{
+       if (!namespace_label_has(ndd, type_guid)) {
+               nsl_set_nlabel(ndd, nd_label, 0); /* N/A */
+               return;
+       }
+       nsl_set_nlabel(ndd, nd_label, first ? nlabel : 0xffff);
+}
+
+static void nsl_set_blk_position(struct nvdimm_drvdata *ndd,
+                                struct nd_namespace_label *nd_label,
+                                bool first)
+{
+       if (!namespace_label_has(ndd, type_guid)) {
+               nsl_set_position(ndd, nd_label, 0);
+               return;
+       }
+       nsl_set_position(ndd, nd_label, first ? 0 : 0xffff);
+}
+
 /*
  * 1/ Account all the labels that can be freed after this update
  * 2/ Allocate and write the label to the staging (next) index
@@ -1019,45 +1117,18 @@ static int __blk_label_update(struct nd_region *nd_region,
                nsl_set_name(ndd, nd_label, nsblk->alt_name);
                nsl_set_flags(ndd, nd_label, NSLABEL_FLAG_LOCAL);
 
-               /*
-                * Use the presence of the type_guid as a flag to
-                * determine isetcookie usage and nlabel + position
-                * policy for blk-aperture namespaces.
-                */
-               if (namespace_label_has(ndd, type_guid)) {
-                       if (i == min_dpa_idx) {
-                               nsl_set_nlabel(ndd, nd_label, nsblk->num_resources);
-                               nsl_set_position(ndd, nd_label, 0);
-                       } else {
-                               nsl_set_nlabel(ndd, nd_label, 0xffff);
-                               nsl_set_position(ndd, nd_label, 0xffff);
-                       }
-                       nsl_set_isetcookie(ndd, nd_label, nd_set->cookie2);
-               } else {
-                       nsl_set_nlabel(ndd, nd_label, 0); /* N/A */
-                       nsl_set_position(ndd, nd_label, 0); /* N/A */
-                       nsl_set_isetcookie(ndd, nd_label, 0); /* N/A */
-               }
+               nsl_set_blk_nlabel(ndd, nd_label, nsblk->num_resources,
+                                  i == min_dpa_idx);
+               nsl_set_blk_position(ndd, nd_label, i == min_dpa_idx);
+               nsl_set_blk_isetcookie(ndd, nd_label, nd_set->cookie2);
 
                nsl_set_dpa(ndd, nd_label, res->start);
                nsl_set_rawsize(ndd, nd_label, resource_size(res));
                nsl_set_lbasize(ndd, nd_label, nsblk->lbasize);
                nsl_set_slot(ndd, nd_label, slot);
-               if (namespace_label_has(ndd, type_guid))
-                       guid_copy(&nd_label->type_guid, &nd_set->type_guid);
-               if (namespace_label_has(ndd, abstraction_guid))
-                       guid_copy(&nd_label->abstraction_guid,
-                                       to_abstraction_guid(ndns->claim_class,
-                                               &nd_label->abstraction_guid));
-
-               if (namespace_label_has(ndd, checksum)) {
-                       u64 sum;
-
-                       nsl_set_checksum(ndd, nd_label, 0);
-                       sum = nd_fletcher64(nd_label,
-                                       sizeof_namespace_label(ndd), 1);
-                       nsl_set_checksum(ndd, nd_label, sum);
-               }
+               nsl_set_type_guid(ndd, nd_label, &nd_set->type_guid);
+               nsl_set_claim_class(ndd, nd_label, ndns->claim_class);
+               nsl_calculate_checksum(ndd, nd_label);
 
                /* update label */
                offset = nd_label_offset(ndd, nd_label);