btrfs-progs: fix unaligned access calculating raid56 data
authorDavid Sterba <dsterba@suse.com>
Wed, 27 Jul 2016 20:30:52 +0000 (22:30 +0200)
committerDavid Sterba <dsterba@suse.com>
Thu, 28 Jul 2016 12:08:30 +0000 (14:08 +0200)
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>
volumes.c

index b42a412..26bf6c5 100644 (file)
--- 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);
                        }
                }
        }