summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.com>2016-07-27 22:30:52 +0200
committerDavid Sterba <dsterba@suse.com>2016-07-28 14:08:30 +0200
commit24f1713777f02300d0c48ddc142b2c711e462b65 (patch)
tree76105362b4c476b7304a469d94c544d7753c527b
parent1c47e5b03922772c1a9429c7817cc728c99e2530 (diff)
btrfs-progs: fix unaligned access calculating raid56 data
The extent_buffer::data might be unaligned wrt unsigned long, depends on acutal layout of the structure and width of the int types. Use explicit unaligned access helpers. Reported-by: Anatoly Pugachev <matorola@gmail.com> Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--volumes.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/volumes.c b/volumes.c
index b42a4126..26bf6c54 100644
--- a/volumes.c
+++ b/volumes.c
@@ -2154,9 +2154,14 @@ int write_raid56_with_parity(struct btrfs_fs_info *info,
ebs[multi->num_stripes - 1] = p_eb;
memcpy(p_eb->data, ebs[0]->data, stripe_len);
for (j = 1; j < multi->num_stripes - 1; j++) {
- for (i = 0; i < stripe_len; i += sizeof(unsigned long)) {
- *(unsigned long *)(p_eb->data + i) ^=
- *(unsigned long *)(ebs[j]->data + i);
+ for (i = 0; i < stripe_len; i += sizeof(u64)) {
+ u64 p_eb_data;
+ u64 ebs_data;
+
+ p_eb_data = get_unaligned_64(p_eb->data + i);
+ ebs_data = get_unaligned_64(ebs[j]->data + i);
+ p_eb_data ^= ebs_data;
+ put_unaligned_64(p_eb_data, p_eb->data + i);
}
}
}