btrfs-progs: fix unaligned access in raid6 calculations

The raid6 code matches kernel implementation that also does the
unaligned access. So to keep the code close, add helpers for unaligned
native access and use them. The helpers are local as we don't plan to
use them elsewhere.

Reported-by: Anatoly Pugachev <matorola@gmail.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
David Sterba 2016-07-28 19:56:20 +02:00
parent 4e4c1e6039
commit af1812090b
1 changed files with 12 additions and 4 deletions

16
raid6.c
View File

@ -10,6 +10,10 @@
* *
* ----------------------------------------------------------------------- */ * ----------------------------------------------------------------------- */
/*
* Added helpers for unaligned native int access
*/
/* /*
* raid6int1.c * raid6int1.c
* *
@ -33,11 +37,15 @@
# define NSIZE 8 # define NSIZE 8
# define NSHIFT 3 # define NSHIFT 3
typedef uint64_t unative_t; typedef uint64_t unative_t;
#define put_unaligned_native(val,p) put_unaligned_64((val),(p))
#define get_unaligned_native(p) get_unaligned_64((p))
#else #else
# define NBYTES(x) ((x) * 0x01010101U) # define NBYTES(x) ((x) * 0x01010101U)
# define NSIZE 4 # define NSIZE 4
# define NSHIFT 2 # define NSHIFT 2
typedef uint32_t unative_t; typedef uint32_t unative_t;
#define put_unaligned_native(val,p) put_unaligned_32((val),(p))
#define get_unaligned_native(p) get_unaligned_32((p))
#endif #endif
/* /*
@ -84,9 +92,9 @@ void raid6_gen_syndrome(int disks, size_t bytes, void **ptrs)
q = dptr[z0+2]; /* RS syndrome */ q = dptr[z0+2]; /* RS syndrome */
for ( d = 0 ; d < bytes ; d += NSIZE*1 ) { for ( d = 0 ; d < bytes ; d += NSIZE*1 ) {
wq0 = wp0 = *(unative_t *)&dptr[z0][d+0*NSIZE]; wq0 = wp0 = get_unaligned_native(&dptr[z0][d+0*NSIZE]);
for ( z = z0-1 ; z >= 0 ; z-- ) { for ( z = z0-1 ; z >= 0 ; z-- ) {
wd0 = *(unative_t *)&dptr[z][d+0*NSIZE]; wd0 = get_unaligned_native(&dptr[z][d+0*NSIZE]);
wp0 ^= wd0; wp0 ^= wd0;
w20 = MASK(wq0); w20 = MASK(wq0);
w10 = SHLBYTE(wq0); w10 = SHLBYTE(wq0);
@ -94,8 +102,8 @@ void raid6_gen_syndrome(int disks, size_t bytes, void **ptrs)
w10 ^= w20; w10 ^= w20;
wq0 = w10 ^ wd0; wq0 = w10 ^ wd0;
} }
*(unative_t *)&p[d+NSIZE*0] = wp0; put_unaligned_native(wp0, &p[d+NSIZE*0]);
*(unative_t *)&q[d+NSIZE*0] = wq0; put_unaligned_native(wq0, &q[d+NSIZE*0]);
} }
} }