Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dm space map common: memcpy the disk root to ensure it's arch aligned

The metadata_space_map_root passed to sm_ll_open_metadata() may or may
not be arch aligned, use memcpy to ensure it is. This is not a fast
path so the extra memcpy doesn't hurt us.

Long-term it'd be better to use the kernel's alignment infrastructure to
remove the memcpy()s that are littered across persistent-data (btree,
array, space-maps, etc).

Signed-off-by: Joe Thornber <ejt@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>

authored by

Joe Thornber and committed by
Mike Snitzer
3ba3ba1e 602548bd

+11 -5
+11 -5
drivers/md/persistent-data/dm-space-map-common.c
··· 626 626 void *root_le, size_t len) 627 627 { 628 628 int r; 629 - struct disk_sm_root *smr = root_le; 629 + struct disk_sm_root smr; 630 630 631 631 if (len < sizeof(struct disk_sm_root)) { 632 632 DMERR("sm_metadata root too small"); 633 633 return -ENOMEM; 634 634 } 635 + 636 + /* 637 + * We don't know the alignment of the root_le buffer, so need to 638 + * copy into a new structure. 639 + */ 640 + memcpy(&smr, root_le, sizeof(smr)); 635 641 636 642 r = sm_ll_init(ll, tm); 637 643 if (r < 0) ··· 650 644 ll->max_entries = metadata_ll_max_entries; 651 645 ll->commit = metadata_ll_commit; 652 646 653 - ll->nr_blocks = le64_to_cpu(smr->nr_blocks); 654 - ll->nr_allocated = le64_to_cpu(smr->nr_allocated); 655 - ll->bitmap_root = le64_to_cpu(smr->bitmap_root); 656 - ll->ref_count_root = le64_to_cpu(smr->ref_count_root); 647 + ll->nr_blocks = le64_to_cpu(smr.nr_blocks); 648 + ll->nr_allocated = le64_to_cpu(smr.nr_allocated); 649 + ll->bitmap_root = le64_to_cpu(smr.bitmap_root); 650 + ll->ref_count_root = le64_to_cpu(smr.ref_count_root); 657 651 658 652 return ll->open_index(ll); 659 653 }