1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| __weak long __pmem_direct_access(struct pmem_device *pmem, pgoff_t pgoff, long nr_pages, enum dax_access_mode mode, void **kaddr, pfn_t *pfn) { resource_size_t offset = PFN_PHYS(pgoff) + pmem->data_offset; sector_t sector = PFN_PHYS(pgoff) >> SECTOR_SHIFT; unsigned int num = PFN_PHYS(nr_pages) >> SECTOR_SHIFT; struct badblocks *bb = &pmem->bb; sector_t first_bad; int num_bad;
if (kaddr) *kaddr = pmem->virt_addr + offset; if (pfn) *pfn = phys_to_pfn_t(pmem->phys_addr + offset, pmem->pfn_flags);
if (bb->count && badblocks_check(bb, sector, num, &first_bad, &num_bad)) { long actual_nr;
if (mode != DAX_RECOVERY_WRITE) return -EIO;
actual_nr = PHYS_PFN( PAGE_ALIGN((first_bad - sector) << SECTOR_SHIFT)); dev_dbg(pmem->bb.dev, "start sector(%llu), nr_pages(%ld), first_bad(%llu), actual_nr(%ld)\n", sector, nr_pages, first_bad, actual_nr); if (actual_nr) return actual_nr; return 1; }
if (bb->count) return nr_pages; return PHYS_PFN(pmem->size - pmem->pfn_pad - offset); }
|