summaryrefslogtreecommitdiff
path: root/drivers/nvdimm/btt_devs.c
diff options
context:
space:
mode:
authorVishal Verma <vishal.l.verma@intel.com>2015-07-29 14:58:09 -0600
committerDan Williams <dan.j.williams@intel.com>2015-08-14 13:43:04 -0400
commit6ec689542b5bc516187917d49b112847dfb75b0b (patch)
treec8351f8cc5140510800ab2098259133de122ae17 /drivers/nvdimm/btt_devs.c
parentab45e7632717b811e0786e46ca5ad279cb731b66 (diff)
libnvdimm, btt: write and validate parent_uuid
When a BTT is instantiated on a namespace it must validate the namespace uuid matches the 'parent_uuid' stored in the btt superblock. This property enforces that changing the namespace UUID invalidates all former BTT instances on that storage. For "IO namespaces" that don't have a label or UUID, the parent_uuid is set to zero, and this validation is skipped. For such cases, old BTTs have to be invalidated by forcing the namespace to raw mode, and overwriting the BTT info blocks. Based on a patch by Dan Williams <dan.j.williams@intel.com> Signed-off-by: Vishal Verma <vishal.l.verma@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/nvdimm/btt_devs.c')
-rw-r--r--drivers/nvdimm/btt_devs.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/nvdimm/btt_devs.c b/drivers/nvdimm/btt_devs.c
index 18e0663e922c..242ae1c550ad 100644
--- a/drivers/nvdimm/btt_devs.c
+++ b/drivers/nvdimm/btt_devs.c
@@ -342,24 +342,37 @@ struct device *nd_btt_create(struct nd_region *nd_region)
return dev;
}
+static bool uuid_is_null(u8 *uuid)
+{
+ static const u8 null_uuid[16];
+
+ return (memcmp(uuid, null_uuid, 16) == 0);
+}
+
/**
* nd_btt_arena_is_valid - check if the metadata layout is valid
* @nd_btt: device with BTT geometry and backing device info
* @super: pointer to the arena's info block being tested
*
* Check consistency of the btt info block with itself by validating
- * the checksum.
+ * the checksum, and with the parent namespace by verifying the
+ * parent_uuid contained in the info block with the one supplied in.
*
* Returns:
* false for an invalid info block, true for a valid one
*/
bool nd_btt_arena_is_valid(struct nd_btt *nd_btt, struct btt_sb *super)
{
+ const u8 *parent_uuid = nd_dev_to_uuid(&nd_btt->ndns->dev);
u64 checksum;
if (memcmp(super->signature, BTT_SIG, BTT_SIG_LEN) != 0)
return false;
+ if (!uuid_is_null(super->parent_uuid))
+ if (memcmp(super->parent_uuid, parent_uuid, 16) != 0)
+ return false;
+
checksum = le64_to_cpu(super->checksum);
super->checksum = 0;
if (checksum != nd_btt_sb_checksum(super))