Skip to content
Permalink
Browse files

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>
  • Loading branch information
kdave committed Jul 28, 2016
1 parent 01dbda9 commit 44b35e94facf820d2c2d8e1be631bf40d68dff8d
Showing with 12 additions and 4 deletions.
  1. +12 −4 raid6.c
16 raid6.c
@@ -10,6 +10,10 @@
*
* ----------------------------------------------------------------------- */

/*
* Added helpers for unaligned native int access
*/

/*
* raid6int1.c
*
@@ -33,11 +37,15 @@
# define NSIZE 8
# define NSHIFT 3
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
# define NBYTES(x) ((x) * 0x01010101U)
# define NSIZE 4
# define NSHIFT 2
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

/*
@@ -84,18 +92,18 @@ void raid6_gen_syndrome(int disks, size_t bytes, void **ptrs)
q = dptr[z0+2]; /* RS syndrome */

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-- ) {
wd0 = *(unative_t *)&dptr[z][d+0*NSIZE];
wd0 = get_unaligned_native(&dptr[z][d+0*NSIZE]);
wp0 ^= wd0;
w20 = MASK(wq0);
w10 = SHLBYTE(wq0);
w20 &= NBYTES(0x1d);
w10 ^= w20;
wq0 = w10 ^ wd0;
}
*(unative_t *)&p[d+NSIZE*0] = wp0;
*(unative_t *)&q[d+NSIZE*0] = wq0;
put_unaligned_native(wp0, &p[d+NSIZE*0]);
put_unaligned_native(wq0, &q[d+NSIZE*0]);
}
}

0 comments on commit 44b35e9

Please sign in to comment.
You can’t perform that action at this time.