diff options
Diffstat (limited to 'drivers/nvdimm')
-rw-r--r-- | drivers/nvdimm/pmem.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 042baec56931..608fc4464574 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c | |||
@@ -164,14 +164,22 @@ static int pmem_rw_page(struct block_device *bdev, sector_t sector, | |||
164 | } | 164 | } |
165 | 165 | ||
166 | static long pmem_direct_access(struct block_device *bdev, sector_t sector, | 166 | static long pmem_direct_access(struct block_device *bdev, sector_t sector, |
167 | void __pmem **kaddr, pfn_t *pfn) | 167 | void __pmem **kaddr, pfn_t *pfn, long size) |
168 | { | 168 | { |
169 | struct pmem_device *pmem = bdev->bd_queue->queuedata; | 169 | struct pmem_device *pmem = bdev->bd_queue->queuedata; |
170 | resource_size_t offset = sector * 512 + pmem->data_offset; | 170 | resource_size_t offset = sector * 512 + pmem->data_offset; |
171 | 171 | ||
172 | if (unlikely(is_bad_pmem(&pmem->bb, sector, size))) | ||
173 | return -EIO; | ||
172 | *kaddr = pmem->virt_addr + offset; | 174 | *kaddr = pmem->virt_addr + offset; |
173 | *pfn = phys_to_pfn_t(pmem->phys_addr + offset, pmem->pfn_flags); | 175 | *pfn = phys_to_pfn_t(pmem->phys_addr + offset, pmem->pfn_flags); |
174 | 176 | ||
177 | /* | ||
178 | * If badblocks are present, limit known good range to the | ||
179 | * requested range. | ||
180 | */ | ||
181 | if (unlikely(pmem->bb.count)) | ||
182 | return size; | ||
175 | return pmem->size - pmem->pfn_pad - offset; | 183 | return pmem->size - pmem->pfn_pad - offset; |
176 | } | 184 | } |
177 | 185 | ||