diff options
author | Joe Thornber <ejt@redhat.com> | 2015-11-19 08:03:36 -0500 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2017-02-16 13:02:54 -0500 |
commit | 3ba3ba1e8411532dc4a05b4e8932c9e358d70a44 (patch) | |
tree | 163e9a4f68dd4ffddf87ba4b3f92dd67a39a56ef /drivers/md | |
parent | 602548bdd5ac4ed7025d992e3ad61a628af4c500 (diff) |
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>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/persistent-data/dm-space-map-common.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/drivers/md/persistent-data/dm-space-map-common.c b/drivers/md/persistent-data/dm-space-map-common.c index 4c28608a0c94..829b4ce057d8 100644 --- a/drivers/md/persistent-data/dm-space-map-common.c +++ b/drivers/md/persistent-data/dm-space-map-common.c | |||
@@ -626,13 +626,19 @@ int sm_ll_open_metadata(struct ll_disk *ll, struct dm_transaction_manager *tm, | |||
626 | void *root_le, size_t len) | 626 | void *root_le, size_t len) |
627 | { | 627 | { |
628 | int r; | 628 | int r; |
629 | struct disk_sm_root *smr = root_le; | 629 | struct disk_sm_root smr; |
630 | 630 | ||
631 | if (len < sizeof(struct disk_sm_root)) { | 631 | if (len < sizeof(struct disk_sm_root)) { |
632 | DMERR("sm_metadata root too small"); | 632 | DMERR("sm_metadata root too small"); |
633 | return -ENOMEM; | 633 | return -ENOMEM; |
634 | } | 634 | } |
635 | 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)); | ||
641 | |||
636 | r = sm_ll_init(ll, tm); | 642 | r = sm_ll_init(ll, tm); |
637 | if (r < 0) | 643 | if (r < 0) |
638 | return r; | 644 | return r; |
@@ -644,10 +650,10 @@ int sm_ll_open_metadata(struct ll_disk *ll, struct dm_transaction_manager *tm, | |||
644 | ll->max_entries = metadata_ll_max_entries; | 650 | ll->max_entries = metadata_ll_max_entries; |
645 | ll->commit = metadata_ll_commit; | 651 | ll->commit = metadata_ll_commit; |
646 | 652 | ||
647 | ll->nr_blocks = le64_to_cpu(smr->nr_blocks); | 653 | ll->nr_blocks = le64_to_cpu(smr.nr_blocks); |
648 | ll->nr_allocated = le64_to_cpu(smr->nr_allocated); | 654 | ll->nr_allocated = le64_to_cpu(smr.nr_allocated); |
649 | ll->bitmap_root = le64_to_cpu(smr->bitmap_root); | 655 | ll->bitmap_root = le64_to_cpu(smr.bitmap_root); |
650 | ll->ref_count_root = le64_to_cpu(smr->ref_count_root); | 656 | ll->ref_count_root = le64_to_cpu(smr.ref_count_root); |
651 | 657 | ||
652 | return ll->open_index(ll); | 658 | return ll->open_index(ll); |
653 | } | 659 | } |