libnvdimm/labels: Add a checksum calculation helper
authorDan Williams <dan.j.williams@intel.com>
Tue, 24 Aug 2021 16:05:46 +0000 (09:05 -0700)
committerDan Williams <dan.j.williams@intel.com>
Tue, 24 Aug 2021 19:08:28 +0000 (12:08 -0700)
In preparation for LIBNVDIMM to manage labels on CXL devices deploy
helpers that abstract the label type from the implementation. The CXL
label format is mostly similar to the EFI label format with concepts /
fields added, like dynamic region creation and label type guids, and
other concepts removed like BLK-mode and interleave-set-cookie ids.

CXL labels support checksums by default, but early versions of the EFI
labels did not. Add a validate function that can return true in the case
the label format does not implement a checksum.

Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Link: https://lore.kernel.org/r/162982114637.1124374.6966639787307077105.stgit@dwillia2-desk3.amr.corp.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
drivers/nvdimm/label.c

index b40a4eda1d899b4bb6074031757cafdd6672f5a5..3f73412dd4380b5d3c400b2903bf3eef42927017 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)
@@ -812,13 +828,7 @@ static int __pmem_label_update(struct nd_region *nd_region,
                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_calculate_checksum(ndd, nd_label);
        nd_dbg_dpa(nd_region, ndd, res, "\n");
 
        /* update label */
@@ -1049,15 +1059,7 @@ static int __blk_label_update(struct nd_region *nd_region,
                        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_calculate_checksum(ndd, nd_label);
 
                /* update label */
                offset = nd_label_offset(ndd, nd_label);