Btrfs on SPARC64 reports lots of warning about non aligned address in btrfs_csum_final : [ 1523.941667] Kernel unaligned access at TPC[100e4034] btrfs_csum_final+0x38/0x3c [btrfs] [ 1523.961335] Kernel unaligned access at TPC[100e4034] btrfs_csum_final+0x38/0x3c [btrfs] [ 1554.143978] Kernel unaligned access at TPC[100e4034] btrfs_csum_final+0x38/0x3c [btrfs] [ 1554.158473] Kernel unaligned access at TPC[100e4034] btrfs_csum_final+0x38/0x3c [btrfs] [ 1589.331232] Kernel unaligned access at TPC[100e4034] btrfs_csum_final+0x38/0x3c [btrfs] [ 1589.338031] Kernel unaligned access at TPC[100e4034] btrfs_csum_final+0x38/0x3c [btrfs] [ 1619.461949] Kernel unaligned access at TPC[100e4034] btrfs_csum_final+0x38/0x3c [btrfs] [ 1619.479549] Kernel unaligned access at TPC[100e4034] btrfs_csum_final+0x38/0x3c [btrfs] [ 1654.815533] Kernel unaligned access at TPC[100e4034] btrfs_csum_final+0x38/0x3c [btrfs] [ 1654.827057] Kernel unaligned access at TPC[100e4034] btrfs_csum_final+0x38/0x3c [btrfs] [ 1685.169193] Kernel unaligned access at TPC[100e4034] btrfs_csum_final+0x38/0x3c [btrfs] [ 1685.176572] Kernel unaligned access at TPC[100e4034] btrfs_csum_final+0x38/0x3c [btrfs] etc etc etc No other messages about btrfs are logged except this only one. Kernel has been compiled with "Optimize for size", will try with a less aggressive option.
Created attachment 49992 [details] use put_unaligned when arch does not have efficient unaligned access Can you please retest with this patch? Thanks.
With the patch applied, I am not able to mount a btrfs partition: [ 2630.494725] ------------[ cut here ]------------ [ 2630.494897] WARNING: at fs/btrfs/extent_io.c:3706 write_extent_buffer+0xc8/0x128 [btrfs]() [ 2630.494940] Modules linked in: btrfs lzo_decompress lzo_compress crc32c libcrc32c ipv6 dm_mod sg tg3 libphy [ 2630.495019] Call Trace: [ 2630.495132] [000000001018d83c] write_extent_buffer+0xc8/0x128 [btrfs] [ 2630.495250] [0000000010195210] btrfs_read_sys_array+0x3c/0x314 [btrfs] [ 2630.495360] [000000001015e3f8] open_ctree+0xf18/0x1864 [btrfs] [ 2630.495457] [0000000010135014] btrfs_mount+0x22c/0x430 [btrfs] [ 2630.495483] [00000000004ef1bc] vfs_kern_mount+0x50/0x144 [ 2630.495500] [00000000004ef2f0] do_kern_mount+0x24/0xbc [ 2630.495524] [0000000000507b8c] do_mount+0x804/0x86c [ 2630.495546] [00000000005261d0] compat_sys_mount+0x1c8/0x20c [ 2630.495569] [0000000000406114] linux_sparc_syscall32+0x34/0x40 [ 2630.495582] ---[ end trace 0ebe577f3ebd0623 ]--- [ 2630.502394] btrfs: sdb1 checksum verify failed on 20971520 wanted 3CC1A21C found 1C000000 level 0 [ 2630.508382] btrfs: sdb1 checksum verify failed on 20971520 wanted 3CC1A21C found 1C000000 level 0 [ 2630.512349] btrfs: sdb1 checksum verify failed on 20971520 wanted 3CC1A21C found 1C000000 level 0 [ 2630.512393] btrfs: failed to read chunk root on sdb1 [ 2630.518917] btrfs: open_ctree failed
I do not know for sure, but I suspect some type mismatch inside put_unaligned(~cpu_to_le32(crc), result); where the ~(...) expression could be upcasted to long and then wrongly converted back to u32. The value 1C000000 has one byte equal to the expected checksum. Please test this patch. Thanks. @@ -198,7 +198,12 @@ u32 btrfs_csum_data(struct btrfs_root *root, char *data, u32 seed, size_t len) void btrfs_csum_final(u32 crc, char *result) { +#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS *(__le32 *)result = ~cpu_to_le32(crc); +#else + crc = ~cpu_to_le32(crc); + put_unaligned(crc, result); +#endif } /*
We are approaching! If I have that code: void btrfs_csum_final(u32 crc, char *result) { #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS *(__le32 *)result = ~cpu_to_le32(crc); #else __le32 r = ~cpu_to_le32(crc); printk("btrfs_csum_data(): ~crc=%x / crc=%x\n", r, crc); put_unaligned(r, result); #endif } I have this in the system log: [ 3376.441367] btrfs_csum_data(): ~crc=d3da8696 / crc=6979252c [ 3376.441388] btrfs: sdb1 checksum verify failed on 20971520 wanted D3DA8696 found 96000000 level 0 [ 3376.446227] btrfs_csum_data(): ~crc=d3da8696 / crc=6979252c [ 3376.446249] btrfs: sdb1 checksum verify failed on 20971520 wanted D3DA8696 found 96000000 level 0 [ 3376.451327] btrfs_csum_data(): ~crc=d3da8696 / crc=6979252c [ 3376.451349] btrfs: sdb1 checksum verify failed on 20971520 wanted D3DA8696 found 96000000 level 0 [ 3376.451394] btrfs: failed to read chunk root on sdb1 [ 3376.457137] btrfs: open_ctree failed so my 'r' variable holds the correct value, the troubles seems to come from 'result' the 96 in 0x96000000 seems to be the 96 of 0xD3DA8696. SPARC64 are big endian CPU, I suspect something related to byte order and/or alignment of the resulting 32 bit integer.
The crc argument comes in CPU order and finally should be stored in LE order. The bitwise not does not affect endianity. Under these assumptions, I think this should work: put_unaligned_le32(~crc, result) (ie. without the cpu_to_le32 conversion). Please test, thanks!
Problem solved! Altought I still have still have the warning (linux-2.6.38 final) : [ 945.426694] ------------[ cut here ]------------ [ 945.426857] WARNING: at fs/btrfs/extent_io.c:3787 write_extent_buffer+0xc8/0x128 [btrfs]() [ 945.426872] Modules linked in: btrfs lzo_decompress lzo_compress crc32c libcrc32c ipv6 dm_mod tg3 sg libphy [ 945.426917] Call Trace: [ 945.427062] [0000000010217ad0] write_extent_buffer+0xc8/0x128 [btrfs] [ 945.427229] [000000001021f5c4] btrfs_read_sys_array+0x3c/0x314 [btrfs] [ 945.427338] [00000000101e84b8] open_ctree+0xf18/0x1864 [btrfs] [ 945.427438] [00000000101bf018] btrfs_mount+0x22c/0x430 [btrfs] [ 945.427466] [00000000004ef2cc] vfs_kern_mount+0x50/0x144 [ 945.427484] [00000000004ef400] do_kern_mount+0x24/0xbc [ 945.427509] [0000000000507d4c] do_mount+0x804/0x86c [ 945.427533] [00000000005264e8] compat_sys_mount+0x1c8/0x20c [ 945.427558] [0000000000406114] linux_sparc_syscall32+0x34/0x40 [ 945.427572] ---[ end trace ccd403344b12822e ]---
Warning reported as a separate issue (bug #31172), David thank you for your efforts.