diff mbox

[v4] libnvdimm: clear poison in mem map metadata

Message ID 148372846406.131989.4828844787582387553.stgit@djiang5-desk3.ch.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Dave Jiang Jan. 6, 2017, 6:47 p.m. UTC
Clearing out the poison in the metadata block of the namespace before
we use it. Range from start + 8k to pfn_sb->dataoff.

Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
 drivers/nvdimm/pfn_devs.c |   25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)
diff mbox

Patch

diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c
index a2ac9e6..fa5ba33 100644
--- a/drivers/nvdimm/pfn_devs.c
+++ b/drivers/nvdimm/pfn_devs.c
@@ -527,11 +527,36 @@  static struct vmem_altmap *__nvdimm_setup_pfn(struct nd_pfn *nd_pfn,
 		.base_pfn = init_altmap_base(base),
 		.reserve = init_altmap_reserve(base),
 	};
+	sector_t sector;
+	resource_size_t meta_start, meta_size;
+	long cleared;
+	unsigned int sz_align;
 
 	memcpy(res, &nsio->res, sizeof(*res));
 	res->start += start_pad;
 	res->end -= end_trunc;
 
+	meta_start = res->start + SZ_8K;
+	meta_size = offset;
+
+	sector = meta_start >> 9;
+	sz_align = ALIGN(meta_size + (meta_start & (512 - 1)), 512);
+
+	if (unlikely(is_bad_pmem(&nsio->bb, sector, sz_align))) {
+		if (!IS_ALIGNED(meta_start, 512) ||
+		    !IS_ALIGNED(meta_size, 512))
+			return ERR_PTR(-EIO);
+
+		cleared = nvdimm_clear_poison(&nd_pfn->dev,
+					      meta_start, meta_size);
+		if (cleared <= 0)
+			return ERR_PTR(-EIO);
+
+		badblocks_clear(&nsio->bb, sector, cleared >> 9);
+		if (cleared != meta_size)
+			return ERR_PTR(-EIO);
+	}
+
 	if (nd_pfn->mode == PFN_MODE_RAM) {
 		if (offset < SZ_8K)
 			return ERR_PTR(-EINVAL);