diff mbox

[v2] libnvdimm: clear poison in mem map metadata

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

Commit Message

Dave Jiang Nov. 18, 2016, 5:06 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 |   30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

Comments

Kani, Toshi Nov. 18, 2016, 10:39 p.m. UTC | #1
On Fri, 2016-11-18 at 10:06 -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>

> ---

>  drivers/nvdimm/pfn_devs.c |   30 ++++++++++++++++++++++++++++++

>  1 file changed, 30 insertions(+)

> 

> diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c

> index cea8350..30c7eaf 100644

> --- a/drivers/nvdimm/pfn_devs.c

> +++ b/drivers/nvdimm/pfn_devs.c

> @@ -527,11 +527,41 @@ 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)) {

> +			cleared = nvdimm_clear_poison(&nd_pfn->dev,

> +						      meta_start,

> meta_size);

> +			if (cleared <= 0)

> +				return ERR_PTR(-EIO);

> +			else {

> +				badblocks_clear(&nsio->bb, sector,

> +						cleared >> 9);

> +				if (cleared != meta_size)

> +					return ERR_PTR(-EIO);

> +

> +			}

> +		} else

> +			return ERR_PTR(-EIO);

> +	}


The above nested if-statements can be changed to:

if (!IS_ALIGNED...)
	return ERR_PTR(-EIO);

cleared = nvdimm_clear_poison(...);
if (cleared <= 0)
	return ERR_PTR(-EIO);

badblocks_clear(...)
if (cleared != meta_size)
	return ERR_PTR(-EIO);

Thanks,
-Toshi
diff mbox

Patch

diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c
index cea8350..30c7eaf 100644
--- a/drivers/nvdimm/pfn_devs.c
+++ b/drivers/nvdimm/pfn_devs.c
@@ -527,11 +527,41 @@  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)) {
+			cleared = nvdimm_clear_poison(&nd_pfn->dev,
+						      meta_start, meta_size);
+			if (cleared <= 0)
+				return ERR_PTR(-EIO);
+			else {
+				badblocks_clear(&nsio->bb, sector,
+						cleared >> 9);
+				if (cleared != meta_size)
+					return ERR_PTR(-EIO);
+
+			}
+		} else
+			return ERR_PTR(-EIO);
+	}
+
 	if (nd_pfn->mode == PFN_MODE_RAM) {
 		if (offset < SZ_8K)
 			return ERR_PTR(-EINVAL);