Skip to content

Commit

Permalink
Fix LZ4 endianness autodetection
Browse files Browse the repository at this point in the history
Endianness detection in LZ4 is broken in user-space builds.  This
bug corrupts compressed data and manifests itself in several ztest
failures.  When LZ4 was originally ported to Illumos ZFS, the proper
checks for Linux were stripped out. The Linux port then inherited
the remaining detection code that works on Illumos but not on Linux.

The current LZ4 endianness check misuses the condition
defined(__BIG_ENDIAN) to indicate a big-endian system.  On Linux
__BIG_ENDIAN is defined uncondtionally in the user-space header
/usr/include/endian.h, regardless of the endianness of the system.
The kernel does not use this header, so only user-space builds are
affected.

While we could fix this by restoring the upstream LZ4 endianness
detection code, reliable checks already exist in
libspl/include/sys/isa_defs.h. This change uses the libspl results
to replace the word-size and endianness checks in LZ4, simplifying
the code and reducing duplication.

Signed-off-by: Ned Bass <[email protected]>
Signed-off-by: Chunwei Chen <[email protected]>
Signed-off-by: DHE <[email protected]>
Signed-off-by: Prakash Surya <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Fixes openzfs#1963
Fixes openzfs#1964
Fixes openzfs#1965
  • Loading branch information
nedbass authored and behlendorf committed Apr 20, 2014
1 parent 4fd762f commit de39ec1
Showing 1 changed file with 3 additions and 8 deletions.
11 changes: 3 additions & 8 deletions module/zfs/lz4.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,7 @@ lz4_decompress_zfs(void *s_start, void *d_start, size_t s_len,
*/

/* 32 or 64 bits ? */
#if (defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) || \
defined(__amd64) || defined(__ppc64__) || defined(_WIN64) || \
defined(__LP64__) || defined(_LP64))
#if defined(_LP64)
#define LZ4_ARCH64 1
#else
#define LZ4_ARCH64 0
Expand All @@ -207,17 +205,14 @@ lz4_decompress_zfs(void *s_start, void *d_start, size_t s_len,
* Little Endian or Big Endian?
* Note: overwrite the below #define if you know your architecture endianess.
*/
#if (defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) || \
defined(_BIG_ENDIAN) || defined(_ARCH_PPC) || defined(__PPC__) || \
defined(__PPC) || defined(PPC) || defined(__powerpc__) || \
defined(__powerpc) || defined(powerpc) || \
((defined(__BYTE_ORDER__)&&(__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))))
#if defined(_BIG_ENDIAN)
#define LZ4_BIG_ENDIAN 1
#else
/*
* Little Endian assumed. PDP Endian and other very rare endian format
* are unsupported.
*/
#undef LZ4_BIG_ENDIAN
#endif

/*
Expand Down

0 comments on commit de39ec1

Please sign in to comment.