diff mbox

[v3] libnvdimm: clear poison in mem map metadata

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

Commit Message

Dave Jiang Nov. 21, 2016, 8:49 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 |   28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

Comments

Kani, Toshi Nov. 23, 2016, 12:07 a.m. UTC | #1
On Mon, 2016-11-21 at 13:49 -0700, Dave Jiang wrote:
> 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>


Thanks for the update.  This looks good to me.

Reviewed-by: Toshi Kani <toshi.kani@hpe.com>


-Toshi
Dan Williams Dec. 29, 2016, 7:43 a.m. UTC | #2
On Mon, Nov 21, 2016 at 12:49 PM, Dave Jiang <dave.jiang@intel.com> wrote:
> 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 |   28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
>
> diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c
> index cea8350..7fa428e 100644
> --- a/drivers/nvdimm/pfn_devs.c
> +++ b/drivers/nvdimm/pfn_devs.c
> @@ -527,11 +527,39 @@ 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 - meta_start + 1;
> +
> +       if (meta_start + meta_size > offset)
> +               return ERR_PTR(-EINVAL);

I missed this patch in the libnvdimm pull request for 4.10-rc1. I
grabbed it for -rc2, but the lines above trigger a regression in the
unit tests. So I dropped it and we should try again with an updated
patch for 4.11 at this point.
diff mbox

Patch

diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c
index cea8350..7fa428e 100644
--- a/drivers/nvdimm/pfn_devs.c
+++ b/drivers/nvdimm/pfn_devs.c
@@ -527,11 +527,39 @@  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 - meta_start + 1;
+
+	if (meta_start + meta_size > offset)
+		return ERR_PTR(-EINVAL);
+
+	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);