From a5eb62e345fc1818d0d8b6181463200a9e8dfe39 Mon Sep 17 00:00:00 2001 From: Miguel Date: Fri, 11 Apr 2008 15:45:51 -0400 Subject: Btrfs: Endianess bug fix for v0.13 with kernels Fix for a endianess BUG when using btrfs v0.13 with kernels older than 2.6.23 Problem: Has of v0.13, btrfs-progs is using crc32c.c equivalent to the one found on linux-2.6.23/lib/libcrc32c.c Since crc32c_le() changed in linux-2.6.23, when running btrfs v0.13 with older kernels we have a missmatch between the versions of crc32c_le() from btrfs-progs and libcrc32c in the kernel. This missmatch causes a bug when using btrfs on big endian machines. Solution: btrfs_crc32c() macro that when compiling for kernels older than 2.6.23, does endianess conversion to parameters and return value of crc32c(). This endianess conversion nullifies the differences in implementation of crc32c_le(). If kernel 2.6.23 or better, it calls crc32c(). Signed-off-by: Miguel Sousa Filipe --- Signed-off-by: Chris Mason --- fs/btrfs/crc32c.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 fs/btrfs/crc32c.h (limited to 'fs/btrfs/crc32c.h') diff --git a/fs/btrfs/crc32c.h b/fs/btrfs/crc32c.h new file mode 100644 index 000000000000..a93255b4ee27 --- /dev/null +++ b/fs/btrfs/crc32c.h @@ -0,0 +1,17 @@ +#include +#include +#include + +/** + * implementation of crc32c_le() changed in linux-2.6.23, + * has of v0.13 btrfs-progs is using the latest version. + * We must workaround older implementations of crc32c_le() + * found on older kernel versions. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) +#define btrfs_crc32c(seed, data, length) \ + __cpu_to_le32( crc32c( __le32_to_cpu(seed), data, length) ) +#else +#define btrfs_crc32c(seed, data, length) \ + crc32c(seed, data, length) +#endif -- cgit v1.2.3 From 3117a77370b6cb902191568e4e647cdcba083d0a Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Mon, 4 Aug 2008 11:10:20 -0400 Subject: Btrfs: Add support for HW assisted crc32c Intel doesn't yet ship hardware to the public with this enabled, but when they do, they will be ready. Original code from: Austin Zhang It is currently disabled, but edit crc32c.h to turn it on. Signed-off-by: Chris Mason --- fs/btrfs/crc32c.h | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 2 deletions(-) (limited to 'fs/btrfs/crc32c.h') diff --git a/fs/btrfs/crc32c.h b/fs/btrfs/crc32c.h index a93255b4ee27..bf6c12e85730 100644 --- a/fs/btrfs/crc32c.h +++ b/fs/btrfs/crc32c.h @@ -1,7 +1,95 @@ +#ifndef __BTRFS_CRC32C__ +#define __BTRFS_CRC32C__ #include #include #include +/* #define CONFIG_BTRFS_HW_SUM 1 */ + +#ifdef CONFIG_BTRFS_HW_SUM +#ifdef CONFIG_X86 +/* + * Using hardware provided CRC32 instruction to accelerate the CRC32 disposal. + * CRC32C polynomial:0x1EDC6F41(BE)/0x82F63B78(LE) + * CRC32 is a new instruction in Intel SSE4.2, the reference can be found at: + * http://www.intel.com/products/processor/manuals/ + * Intel(R) 64 and IA-32 Architectures Software Developer's Manual + * Volume 2A: Instruction Set Reference, A-M + */ + +#include +#include + +#define X86_FEATURE_XMM4_2 (4*32+20) /* Streaming SIMD Extensions-4.2 */ +#define cpu_has_xmm4_2 boot_cpu_has(X86_FEATURE_XMM4_2) + +#ifdef CONFIG_X86_64 +#define REX_PRE "0x48, " +#define SCALE_F 8 +#else +#define REX_PRE +#define SCALE_F 4 +#endif + +static inline u32 btrfs_crc32c_le_hw_byte(u32 crc, unsigned char const *data, + size_t length) +{ + while (length--) { + __asm__ __volatile__( + ".byte 0xf2, 0xf, 0x38, 0xf0, 0xf1" + :"=S"(crc) + :"0"(crc), "c"(*data) + ); + data++; + } + + return crc; +} + +static inline u32 __pure btrfs_crc32c_le_hw(u32 crc, unsigned char const *p, + size_t len) +{ + unsigned int iquotient = len / SCALE_F; + unsigned int iremainder = len % SCALE_F; +#ifdef CONFIG_X86_64 + u64 *ptmp = (u64 *)p; +#else + u32 *ptmp = (u32 *)p; +#endif + + while (iquotient--) { + __asm__ __volatile__( + ".byte 0xf2, " REX_PRE "0xf, 0x38, 0xf1, 0xf1;" + :"=S"(crc) + :"0"(crc), "c"(*ptmp) + ); + ptmp++; + } + + if (iremainder) + crc = btrfs_crc32c_le_hw_byte(crc, (unsigned char *)ptmp, + iremainder); + + return crc; +} +#endif /* CONFIG_BTRFS_HW_SUM */ + +static inline u32 __btrfs_crc32c(u32 crc, unsigned char const *address, + size_t len) +{ +#ifdef CONFIG_BTRFS_HW_SUM + if (cpu_has_xmm4_2) + return btrfs_crc32c_le_hw(crc, address, len); +#endif + return crc32c_le(crc, address, len); +} + +#else + +#define __btrfs_crc32c(seed, data, length) crc32c(seed, data, length) + +#endif /* CONFIG_X86 */ + /** * implementation of crc32c_le() changed in linux-2.6.23, * has of v0.13 btrfs-progs is using the latest version. @@ -10,8 +98,11 @@ */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) #define btrfs_crc32c(seed, data, length) \ - __cpu_to_le32( crc32c( __le32_to_cpu(seed), data, length) ) + __cpu_to_le32( __btrfs_crc32c( __le32_to_cpu(seed), \ + (unsigned char const *)data, length) ) #else #define btrfs_crc32c(seed, data, length) \ - crc32c(seed, data, length) + __btrfs_crc32c(seed, (unsigned char const *)data, length) +#endif #endif + -- cgit v1.2.3 From 2b1f55b0f0d0d1a66470ef4ea2696cd5dd741a12 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Wed, 24 Sep 2008 11:48:04 -0400 Subject: Remove Btrfs compat code for older kernels Btrfs had compatibility code for kernels back to 2.6.18. These have been removed, and will be maintained in a separate backport git tree from now on. Signed-off-by: Chris Mason --- fs/btrfs/crc32c.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'fs/btrfs/crc32c.h') diff --git a/fs/btrfs/crc32c.h b/fs/btrfs/crc32c.h index bf6c12e85730..4f0fefed132a 100644 --- a/fs/btrfs/crc32c.h +++ b/fs/btrfs/crc32c.h @@ -96,13 +96,7 @@ static inline u32 __btrfs_crc32c(u32 crc, unsigned char const *address, * We must workaround older implementations of crc32c_le() * found on older kernel versions. */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) -#define btrfs_crc32c(seed, data, length) \ - __cpu_to_le32( __btrfs_crc32c( __le32_to_cpu(seed), \ - (unsigned char const *)data, length) ) -#else #define btrfs_crc32c(seed, data, length) \ __btrfs_crc32c(seed, (unsigned char const *)data, length) #endif -#endif -- cgit v1.2.3 From d352ac68148b69937d39ca5d48bcc4478e118dbf Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Mon, 29 Sep 2008 15:18:18 -0400 Subject: Btrfs: add and improve comments This improves the comments at the top of many functions. It didn't dive into the guts of functions because I was trying to avoid merging problems with the new allocator and back reference work. extent-tree.c and volumes.c were both skipped, and there is definitely more work todo in cleaning and commenting the code. Signed-off-by: Chris Mason --- fs/btrfs/crc32c.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'fs/btrfs/crc32c.h') diff --git a/fs/btrfs/crc32c.h b/fs/btrfs/crc32c.h index 4f0fefed132a..1eaf11d334fd 100644 --- a/fs/btrfs/crc32c.h +++ b/fs/btrfs/crc32c.h @@ -1,3 +1,21 @@ +/* + * Copyright (C) 2008 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License v2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + #ifndef __BTRFS_CRC32C__ #define __BTRFS_CRC32C__ #include -- cgit v1.2.3 From 755efdc3c4d3b42d5ffcef0f4d6e5b37ecd3bf21 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Wed, 7 Jan 2009 19:56:59 -0500 Subject: Btrfs: Drop the hardware crc32c asm code This is already in the arch specific directories in mainline and shouldn't be copied into btrfs. Signed-off-by: Chris Mason --- fs/btrfs/crc32c.h | 97 ++----------------------------------------------------- 1 file changed, 3 insertions(+), 94 deletions(-) (limited to 'fs/btrfs/crc32c.h') diff --git a/fs/btrfs/crc32c.h b/fs/btrfs/crc32c.h index 1eaf11d334fd..6e1b3de36700 100644 --- a/fs/btrfs/crc32c.h +++ b/fs/btrfs/crc32c.h @@ -18,103 +18,12 @@ #ifndef __BTRFS_CRC32C__ #define __BTRFS_CRC32C__ -#include #include -#include -/* #define CONFIG_BTRFS_HW_SUM 1 */ - -#ifdef CONFIG_BTRFS_HW_SUM -#ifdef CONFIG_X86 /* - * Using hardware provided CRC32 instruction to accelerate the CRC32 disposal. - * CRC32C polynomial:0x1EDC6F41(BE)/0x82F63B78(LE) - * CRC32 is a new instruction in Intel SSE4.2, the reference can be found at: - * http://www.intel.com/products/processor/manuals/ - * Intel(R) 64 and IA-32 Architectures Software Developer's Manual - * Volume 2A: Instruction Set Reference, A-M - */ - -#include -#include - -#define X86_FEATURE_XMM4_2 (4*32+20) /* Streaming SIMD Extensions-4.2 */ -#define cpu_has_xmm4_2 boot_cpu_has(X86_FEATURE_XMM4_2) - -#ifdef CONFIG_X86_64 -#define REX_PRE "0x48, " -#define SCALE_F 8 -#else -#define REX_PRE -#define SCALE_F 4 -#endif - -static inline u32 btrfs_crc32c_le_hw_byte(u32 crc, unsigned char const *data, - size_t length) -{ - while (length--) { - __asm__ __volatile__( - ".byte 0xf2, 0xf, 0x38, 0xf0, 0xf1" - :"=S"(crc) - :"0"(crc), "c"(*data) - ); - data++; - } - - return crc; -} - -static inline u32 __pure btrfs_crc32c_le_hw(u32 crc, unsigned char const *p, - size_t len) -{ - unsigned int iquotient = len / SCALE_F; - unsigned int iremainder = len % SCALE_F; -#ifdef CONFIG_X86_64 - u64 *ptmp = (u64 *)p; -#else - u32 *ptmp = (u32 *)p; -#endif - - while (iquotient--) { - __asm__ __volatile__( - ".byte 0xf2, " REX_PRE "0xf, 0x38, 0xf1, 0xf1;" - :"=S"(crc) - :"0"(crc), "c"(*ptmp) - ); - ptmp++; - } - - if (iremainder) - crc = btrfs_crc32c_le_hw_byte(crc, (unsigned char *)ptmp, - iremainder); - - return crc; -} -#endif /* CONFIG_BTRFS_HW_SUM */ - -static inline u32 __btrfs_crc32c(u32 crc, unsigned char const *address, - size_t len) -{ -#ifdef CONFIG_BTRFS_HW_SUM - if (cpu_has_xmm4_2) - return btrfs_crc32c_le_hw(crc, address, len); -#endif - return crc32c_le(crc, address, len); -} - -#else - -#define __btrfs_crc32c(seed, data, length) crc32c(seed, data, length) - -#endif /* CONFIG_X86 */ - -/** - * implementation of crc32c_le() changed in linux-2.6.23, - * has of v0.13 btrfs-progs is using the latest version. - * We must workaround older implementations of crc32c_le() - * found on older kernel versions. + * this file used to do more for selecting the HW version of crc32c, + * perhaps it will one day again soon. */ -#define btrfs_crc32c(seed, data, length) \ - __btrfs_crc32c(seed, (unsigned char const *)data, length) +#define btrfs_crc32c(seed, data, length) crc32c(seed, data, length) #endif -- cgit v1.2.3