From patchwork Tue Jul 12 23:21:48 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 9226581 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 5AD0F604DB for ; Tue, 12 Jul 2016 23:22:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4C2D127C14 for ; Tue, 12 Jul 2016 23:22:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3F58F27C8F; Tue, 12 Jul 2016 23:22:33 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7D2DD27F94 for ; Tue, 12 Jul 2016 23:22:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752297AbcGLXW0 (ORCPT ); Tue, 12 Jul 2016 19:22:26 -0400 Received: from mail-pf0-f169.google.com ([209.85.192.169]:36722 "EHLO mail-pf0-f169.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752166AbcGLXWX (ORCPT ); Tue, 12 Jul 2016 19:22:23 -0400 Received: by mail-pf0-f169.google.com with SMTP id t190so11631658pfb.3 for ; Tue, 12 Jul 2016 16:22:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id; bh=rwDsBCzQhOeq4x31nHdNMQ7DE540ryqIHhzlbKWqiy8=; b=qeuo/tg9wBM1i8w/jAKZtfqBoBWi52f7nTET2gCK8AIcqp+jxVFyCnFNf+CG7iF/i8 UbZuLtkcqzqlGRUCadJbrjqh+kvvK8Qm5XXNiQ7CFBYwAOdPdu7gcti7add5PuYT50+O SD5ZnMrrhccwrZVHE7kVVPcQCEc5r8dX19nzItau6HMANB/hL5EgoFo+s6dkHNVSzu4u nY7AxbXozfGBJOeKoU1AqTXVQNgVx548P3xhkRksqD3Tx8zvDJUcpNacSAl/leG5vTsr huF2NaIvluV/9CSBotLKPc/z4CzZc5Z0ZJJx6yabP0Ya5XWe4XOGFFCDYG8s+VDv6HQM 16qQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=rwDsBCzQhOeq4x31nHdNMQ7DE540ryqIHhzlbKWqiy8=; b=Vbw5q4r1sJr9v4hRqDBZGW8Wi+Jp9aBoRWjKQaxsj+ZWRn16vXS8OHfk/rhdXrd1kE /vNKzpX6b86pNWj7PCnIlkm/qJ66vcwSZeeiLQwz+fB8Rpmxed0nSR20synvoJNWAHmb UvbKZrgRZ0wQSwuJF7zSjj9emrn6eqf1byNwwlT4jLJz+xkUJFHRzyVpCWOhXQ6b/bIn NIgIcMBSDSJITtYxhYx1pbjI3iFrg9D1Is0fwTYLumNpNQ9S59qloO4O9TwX/E5EdR9b IC9f7JEHcJWozKVq1DcBS9w4tqkCdOhBw2/vbKiaF29EosclyqkfD2I9eFF0HchJqDME 48ng== X-Gm-Message-State: ALyK8tLCb0pEsQcbprSIVSodhDF3N4eEipghk/pqDbWll0eMwAH7XgyAJQbnuG9J5Rw3FXeV X-Received: by 10.98.95.5 with SMTP id t5mr48856637pfb.103.1468365718828; Tue, 12 Jul 2016 16:21:58 -0700 (PDT) Received: from vader.thefacebook.com ([2620:10d:c090:200::a:da58]) by smtp.gmail.com with ESMTPSA id i69sm6855275pfk.30.2016.07.12.16.21.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 12 Jul 2016 16:21:58 -0700 (PDT) From: Omar Sandoval To: linux-btrfs@vger.kernel.org Cc: Anatoly Pugachev , Feifei Xu Subject: [PATCH] Btrfs: fix extent buffer bitmap tests on big-endian systems Date: Tue, 12 Jul 2016 16:21:48 -0700 Message-Id: X-Mailer: git-send-email 2.9.0 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Omar Sandoval The in-memory bitmap code manipulates words and is therefore sensitive to endianness, while the extent buffer bitmap code addresses bytes and is byte-order agnostic. Because the byte addressing of the extent buffer bitmaps is equivalent to a little-endian in-memory bitmap, the extent buffer bitmap tests fail on big-endian systems. 34b3e6c92af1 ("Btrfs: self-tests: Fix extent buffer bitmap test fail on BE system") worked around another endianness bug in the tests but missed this one because ed9e4afdb055 ("Btrfs: self-tests: Execute page straddling test only when nodesize < PAGE_SIZE") disables this part of the test on ppc64. That change lost the original meaning of the test, however. We really want to test that an equivalent series of operations using the in-memory bitmap API and the extent buffer bitmap API produces equivalent results. To fix this, don't use memcmp_extent_buffer() or write_extent_buffer(); do everything bit-by-bit. Reported-by: Anatoly Pugachev Signed-off-by: Omar Sandoval --- This worked for me on a QEMU-emulated MIPS system. Anatoly, could you try this out and let me know if this fixes your problem? Applies to v4.7-rc7. fs/btrfs/tests/extent-io-tests.c | 82 +++++++++++++++++++++++----------------- 1 file changed, 48 insertions(+), 34 deletions(-) diff --git a/fs/btrfs/tests/extent-io-tests.c b/fs/btrfs/tests/extent-io-tests.c index d19ab0317283..0207279a9fa9 100644 --- a/fs/btrfs/tests/extent-io-tests.c +++ b/fs/btrfs/tests/extent-io-tests.c @@ -273,20 +273,36 @@ out: return ret; } -/** - * test_bit_in_byte - Determine whether a bit is set in a byte - * @nr: bit number to test - * @addr: Address to start counting from - */ -static inline int test_bit_in_byte(int nr, const u8 *addr) +static int check_eb_bitmap(unsigned long *bitmap, struct extent_buffer *eb, + unsigned long len) { - return 1UL & (addr[nr / BITS_PER_BYTE] >> (nr & (BITS_PER_BYTE - 1))); + unsigned long i; + + for (i = 0; i < len * BITS_PER_BYTE; i++) { + int bit, bit1; + + bit = !!test_bit(i, bitmap); + bit1 = !!extent_buffer_test_bit(eb, 0, i); + if (bit1 != bit) { + test_msg("Bits do not match\n"); + return -EINVAL; + } + + bit1 = !!extent_buffer_test_bit(eb, i / BITS_PER_BYTE, + i % BITS_PER_BYTE); + if (bit1 != bit) { + test_msg("Offset bits do not match\n"); + return -EINVAL; + } + } + return 0; } static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb, unsigned long len) { - unsigned long i, x; + unsigned long i, j, x; + int ret; memset(bitmap, 0, len); memset_extent_buffer(eb, 0, 0, len); @@ -297,16 +313,18 @@ static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb, bitmap_set(bitmap, 0, len * BITS_PER_BYTE); extent_buffer_bitmap_set(eb, 0, 0, len * BITS_PER_BYTE); - if (memcmp_extent_buffer(eb, bitmap, 0, len) != 0) { + ret = check_eb_bitmap(bitmap, eb, len); + if (ret) { test_msg("Setting all bits failed\n"); - return -EINVAL; + return ret; } bitmap_clear(bitmap, 0, len * BITS_PER_BYTE); extent_buffer_bitmap_clear(eb, 0, 0, len * BITS_PER_BYTE); - if (memcmp_extent_buffer(eb, bitmap, 0, len) != 0) { + ret = check_eb_bitmap(bitmap, eb, len); + if (ret) { test_msg("Clearing all bits failed\n"); - return -EINVAL; + return ret; } /* Straddling pages test */ @@ -316,9 +334,10 @@ static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb, sizeof(long) * BITS_PER_BYTE); extent_buffer_bitmap_set(eb, PAGE_SIZE - sizeof(long) / 2, 0, sizeof(long) * BITS_PER_BYTE); - if (memcmp_extent_buffer(eb, bitmap, 0, len) != 0) { + ret = check_eb_bitmap(bitmap, eb, len); + if (ret) { test_msg("Setting straddling pages failed\n"); - return -EINVAL; + return ret; } bitmap_set(bitmap, 0, len * BITS_PER_BYTE); @@ -328,9 +347,10 @@ static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb, extent_buffer_bitmap_set(eb, 0, 0, len * BITS_PER_BYTE); extent_buffer_bitmap_clear(eb, PAGE_SIZE - sizeof(long) / 2, 0, sizeof(long) * BITS_PER_BYTE); - if (memcmp_extent_buffer(eb, bitmap, 0, len) != 0) { + ret = check_eb_bitmap(bitmap, eb, len); + if (ret) { test_msg("Clearing straddling pages failed\n"); - return -EINVAL; + return ret; } } @@ -339,28 +359,22 @@ static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb, * something repetitive that could miss some hypothetical off-by-n bug. */ x = 0; + bitmap_clear(bitmap, 0, len * BITS_PER_BYTE); + extent_buffer_bitmap_clear(eb, 0, 0, len * BITS_PER_BYTE); for (i = 0; i < len / sizeof(long); i++) { x = (0x19660dULL * (u64)x + 0x3c6ef35fULL) & 0xffffffffUL; - bitmap[i] = x; - } - write_extent_buffer(eb, bitmap, 0, len); - - for (i = 0; i < len * BITS_PER_BYTE; i++) { - int bit, bit1; - - bit = !!test_bit_in_byte(i, (u8 *)bitmap); - bit1 = !!extent_buffer_test_bit(eb, 0, i); - if (bit1 != bit) { - test_msg("Testing bit pattern failed\n"); - return -EINVAL; + for (j = 0; j < BITS_PER_LONG; j++) { + if (x & (1 << j)) { + bitmap_set(bitmap, i * sizeof(long) + j, 1); + extent_buffer_bitmap_set(eb, 0, i * sizeof(long) + j, 1); + } } + } - bit1 = !!extent_buffer_test_bit(eb, i / BITS_PER_BYTE, - i % BITS_PER_BYTE); - if (bit1 != bit) { - test_msg("Testing bit pattern with offset failed\n"); - return -EINVAL; - } + ret = check_eb_bitmap(bitmap, eb, len); + if (ret) { + test_msg("Random bit pattern failed\n"); + return ret; } return 0;