Skip to content

Commit 274b924

Browse files
JeffMoyerdjbw
authored andcommitted
libnvdimm/pfn: Fix namespace creation on misaligned addresses
Yi reported[1] that after commit a361919 ("libnvdimm/pfn: stop padding pmem namespaces to section alignment"), it was no longer possible to create a device dax namespace with a 1G alignment. The reason was that the pmem region was not itself 1G-aligned. The code happily skips past the first 512M, but fails to account for a now misaligned end offset (since space was allocated starting at that misaligned address, and extending for size GBs). Reintroduce end_trunc, so that the code correctly handles the misaligned end address. This results in the same behavior as before the introduction of the offending commit. [1] https://lists.01.org/pipermail/linux-nvdimm/2019-July/022813.html Fixes: a361919 ("libnvdimm/pfn: stop padding pmem namespaces ...") Reported-and-tested-by: Yi Zhang <[email protected]> Signed-off-by: Jeff Moyer <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Dan Williams <[email protected]>
1 parent a55aa89 commit 274b924

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

drivers/nvdimm/pfn_devs.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,7 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn)
655655
resource_size_t start, size;
656656
struct nd_region *nd_region;
657657
unsigned long npfns, align;
658+
u32 end_trunc;
658659
struct nd_pfn_sb *pfn_sb;
659660
phys_addr_t offset;
660661
const char *sig;
@@ -696,6 +697,7 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn)
696697
size = resource_size(&nsio->res);
697698
npfns = PHYS_PFN(size - SZ_8K);
698699
align = max(nd_pfn->align, (1UL << SUBSECTION_SHIFT));
700+
end_trunc = start + size - ALIGN_DOWN(start + size, align);
699701
if (nd_pfn->mode == PFN_MODE_PMEM) {
700702
/*
701703
* The altmap should be padded out to the block size used
@@ -714,7 +716,7 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn)
714716
return -ENXIO;
715717
}
716718

717-
npfns = PHYS_PFN(size - offset);
719+
npfns = PHYS_PFN(size - offset - end_trunc);
718720
pfn_sb->mode = cpu_to_le32(nd_pfn->mode);
719721
pfn_sb->dataoff = cpu_to_le64(offset);
720722
pfn_sb->npfns = cpu_to_le64(npfns);
@@ -723,6 +725,7 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn)
723725
memcpy(pfn_sb->parent_uuid, nd_dev_to_uuid(&ndns->dev), 16);
724726
pfn_sb->version_major = cpu_to_le16(1);
725727
pfn_sb->version_minor = cpu_to_le16(3);
728+
pfn_sb->end_trunc = cpu_to_le32(end_trunc);
726729
pfn_sb->align = cpu_to_le32(nd_pfn->align);
727730
checksum = nd_sb_checksum((struct nd_gen_sb *) pfn_sb);
728731
pfn_sb->checksum = cpu_to_le64(checksum);

0 commit comments

Comments
 (0)