Skip to content

Commit

Permalink
libnvdimm, pmem: nvdimm_read_bytes() badblocks support
Browse files Browse the repository at this point in the history
Support badblock checking in all the pmem read paths that do not go
through the block layer.  This protects info block reads (btt or pfn) as
well as data reads to a pmem namespace via a btt instance.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
  • Loading branch information
Dan Williams committed Jan 10, 2016
1 parent 57f7f31 commit 710d69c
Showing 1 changed file with 10 additions and 2 deletions.
12 changes: 10 additions & 2 deletions drivers/nvdimm/pmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ static int pmem_attach_disk(struct device *dev,
disk->driverfs_dev = dev;
set_capacity(disk, (pmem->size - pmem->data_offset) / 512);
pmem->pmem_disk = disk;
devm_exit_badblocks(dev, &pmem->bb);
if (devm_init_badblocks(dev, &pmem->bb))
return -ENOMEM;
nvdimm_namespace_add_poison(ndns, &pmem->bb, pmem->data_offset);
Expand All @@ -250,9 +251,13 @@ static int pmem_rw_bytes(struct nd_namespace_common *ndns,
return -EFAULT;
}

if (rw == READ)
if (rw == READ) {
unsigned int sz_align = ALIGN(size + (offset & (512 - 1)), 512);

if (unlikely(is_bad_pmem(&pmem->bb, offset / 512, sz_align)))
return -EIO;
memcpy_from_pmem(buf, pmem->virt_addr + offset, size);
else {
} else {
memcpy_to_pmem(pmem->virt_addr + offset, buf, size);
wmb_pmem();
}
Expand Down Expand Up @@ -427,6 +432,9 @@ static int nd_pmem_probe(struct device *dev)
pmem->ndns = ndns;
dev_set_drvdata(dev, pmem);
ndns->rw_bytes = pmem_rw_bytes;
if (devm_init_badblocks(dev, &pmem->bb))
return -ENOMEM;
nvdimm_namespace_add_poison(ndns, &pmem->bb, 0);

if (is_nd_btt(dev))
return nvdimm_namespace_attach_btt(ndns);
Expand Down

0 comments on commit 710d69c

Please sign in to comment.