Message ID | 147889305624.162244.5399670205091896834.stgit@djiang5-desk3.ch.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
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) >
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)
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(-)