linux-nvdimm.lists.01.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3] libnvdimm: check and clear poison before writing to pmem
@ 2016-11-11 19:37 Dave Jiang
  2016-11-11 19:41 ` Vishal Verma
  0 siblings, 1 reply; 2+ messages in thread
From: Dave Jiang @ 2016-11-11 19:37 UTC (permalink / raw)
  To: vishal.l.verma, dan.j.williams, ross.zwisler; +Cc: linux-nvdimm

We need to clear any poison when we are writing to pmem. The granularity
will be sector size. If it's less then we can't do anything about it
barring corruption.

Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
 drivers/nvdimm/claim.c |   30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/drivers/nvdimm/claim.c b/drivers/nvdimm/claim.c
index d5dc80c..494536c 100644
--- a/drivers/nvdimm/claim.c
+++ b/drivers/nvdimm/claim.c
@@ -226,6 +226,12 @@ static int nsio_rw_bytes(struct nd_namespace_common *ndns,
 		resource_size_t offset, void *buf, size_t size, int rw)
 {
 	struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev);
+	unsigned int sz_align = ALIGN(size + (offset & (512 - 1)), 512);
+	sector_t sector = offset >> 9;
+	int rc = 0;
+
+	if (unlikely(!size))
+		return -EINVAL;
 
 	if (unlikely(offset + size > nsio->size)) {
 		dev_WARN_ONCE(&ndns->dev, 1, "request out of range\n");
@@ -233,17 +239,33 @@ static int nsio_rw_bytes(struct nd_namespace_common *ndns,
 	}
 
 	if (rw == READ) {
-		unsigned int sz_align = ALIGN(size + (offset & (512 - 1)), 512);
-
-		if (unlikely(is_bad_pmem(&nsio->bb, offset / 512, sz_align)))
+		if (unlikely(is_bad_pmem(&nsio->bb, sector, sz_align)))
 			return -EIO;
 		return memcpy_from_pmem(buf, nsio->addr + offset, size);
 	} else {
+
+		if (unlikely(is_bad_pmem(&nsio->bb, sector, sz_align))) {
+			if (IS_ALIGNED(offset, 512) && IS_ALIGNED(size, 512)) {
+				long cleared;
+
+				cleared = nvdimm_clear_poison(&ndns->dev,
+							      offset, size);
+				if (cleared != size) {
+					size = cleared;
+					rc = -EIO;
+				}
+
+				badblocks_clear(&nsio->bb, sector,
+						cleared >> 9);
+			} else
+				rc = -EIO;
+		}
+
 		memcpy_to_pmem(nsio->addr + offset, buf, size);
 		nvdimm_flush(to_nd_region(ndns->dev.parent));
 	}
 
-	return 0;
+	return rc;
 }
 
 int devm_nsio_enable(struct device *dev, struct nd_namespace_io *nsio)

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH v3] libnvdimm: check and clear poison before writing to pmem
  2016-11-11 19:37 [PATCH v3] libnvdimm: check and clear poison before writing to pmem Dave Jiang
@ 2016-11-11 19:41 ` Vishal Verma
  0 siblings, 0 replies; 2+ messages in thread
From: Vishal Verma @ 2016-11-11 19:41 UTC (permalink / raw)
  To: Dave Jiang; +Cc: linux-nvdimm

On 11/11, Dave Jiang wrote:
> We need to clear any poison when we are writing to pmem. The granularity
> will be sector size. If it's less then we can't do anything about it
> barring corruption.
> 
> Signed-off-by: Dave Jiang <dave.jiang@intel.com>
> ---
>  drivers/nvdimm/claim.c |   30 ++++++++++++++++++++++++++----
>  1 file changed, 26 insertions(+), 4 deletions(-)

Looks good!

Reviewed-by: Vishal Verma <vishal.l.verma@intel.com>

> 
> diff --git a/drivers/nvdimm/claim.c b/drivers/nvdimm/claim.c
> index d5dc80c..494536c 100644
> --- a/drivers/nvdimm/claim.c
> +++ b/drivers/nvdimm/claim.c
> @@ -226,6 +226,12 @@ static int nsio_rw_bytes(struct nd_namespace_common *ndns,
>  		resource_size_t offset, void *buf, size_t size, int rw)
>  {
>  	struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev);
> +	unsigned int sz_align = ALIGN(size + (offset & (512 - 1)), 512);
> +	sector_t sector = offset >> 9;
> +	int rc = 0;
> +
> +	if (unlikely(!size))
> +		return -EINVAL;
>  
>  	if (unlikely(offset + size > nsio->size)) {
>  		dev_WARN_ONCE(&ndns->dev, 1, "request out of range\n");
> @@ -233,17 +239,33 @@ static int nsio_rw_bytes(struct nd_namespace_common *ndns,
>  	}
>  
>  	if (rw == READ) {
> -		unsigned int sz_align = ALIGN(size + (offset & (512 - 1)), 512);
> -
> -		if (unlikely(is_bad_pmem(&nsio->bb, offset / 512, sz_align)))
> +		if (unlikely(is_bad_pmem(&nsio->bb, sector, sz_align)))
>  			return -EIO;
>  		return memcpy_from_pmem(buf, nsio->addr + offset, size);
>  	} else {
> +
> +		if (unlikely(is_bad_pmem(&nsio->bb, sector, sz_align))) {
> +			if (IS_ALIGNED(offset, 512) && IS_ALIGNED(size, 512)) {
> +				long cleared;
> +
> +				cleared = nvdimm_clear_poison(&ndns->dev,
> +							      offset, size);
> +				if (cleared != size) {
> +					size = cleared;
> +					rc = -EIO;
> +				}
> +
> +				badblocks_clear(&nsio->bb, sector,
> +						cleared >> 9);
> +			} else
> +				rc = -EIO;
> +		}
> +
>  		memcpy_to_pmem(nsio->addr + offset, buf, size);
>  		nvdimm_flush(to_nd_region(ndns->dev.parent));
>  	}
>  
> -	return 0;
> +	return rc;
>  }
>  
>  int devm_nsio_enable(struct device *dev, struct nd_namespace_io *nsio)
> 
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2016-11-11 19:41 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-11-11 19:37 [PATCH v3] libnvdimm: check and clear poison before writing to pmem Dave Jiang
2016-11-11 19:41 ` Vishal Verma

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).