From patchwork Mon Oct 9 01:51:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qu Wenruo X-Patchwork-Id: 9992101 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 3F2E9602D7 for ; Mon, 9 Oct 2017 01:51:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3DF1A28623 for ; Mon, 9 Oct 2017 01:51:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 32F6E2863B; Mon, 9 Oct 2017 01:51:30 +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.9 required=2.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_HI 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 66AB828623 for ; Mon, 9 Oct 2017 01:51:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751544AbdJIBvX (ORCPT ); Sun, 8 Oct 2017 21:51:23 -0400 Received: from mout.gmx.net ([212.227.17.20]:55718 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751308AbdJIBvW (ORCPT ); Sun, 8 Oct 2017 21:51:22 -0400 Received: from localhost.localdomain ([104.207.157.105]) by mail.gmx.com (mrgmx101 [212.227.17.174]) with ESMTPSA (Nemesis) id 0MTO3f-1dtMMm2a7r-00SKLG; Mon, 09 Oct 2017 03:51:16 +0200 From: Qu Wenruo To: linux-btrfs@vger.kernel.org Cc: dsterba@suse.cz, nborisov@suse.com Subject: [PATCH v4 2/5] btrfs: tree-checker: Enhance btrfs_check_node output Date: Mon, 9 Oct 2017 01:51:03 +0000 Message-Id: <20171009015106.9711-3-quwenruo.btrfs@gmx.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171009015106.9711-1-quwenruo.btrfs@gmx.com> References: <20171009015106.9711-1-quwenruo.btrfs@gmx.com> X-Provags-ID: V03:K0:Nyv8zXrzHAKHRtNRBCUKGrVZ52QqQOLUP2Yh8JZKCeMDgw9wCdk /isey8G0uigJjovYIviqDBxFCLRRn7/VwJTcxzFeKLCpEJVMVylQU81KAcueU6pNSeSRC9O 4ZmEhbowzF+8xxNxnGkXG4VrPGYRBnX1uHNHHQ1e1Kzg/pYwwX/7+hLYlUMwLfmc6iVVC16 Tm1nIa15qhzs+U7TC59kQ== X-UI-Out-Filterresults: notjunk:1; V01:K0:QDgP/p1uQKI=:AwKVDzMjMmtPze58E+C6Hb j4LPXB3DQ2KT50S7DhZNwChle7ypPsPabjwufPIHTMBG2+yKsVovgHd77GdBPZUxxuffGa3o1 l9u7zmfgL5YkCX8i7G4SGpADxnMYgY2oXvzNV4bnbl8KjwzJxnZFnaPEimYMt4Eb34WmTeBeY ZUl4jvZ1BT4cgyTWV6qrxNrPLoL121xo037zY1B+v6Tm/cH+6xoYMRLHzx7MCJq9tYlsKVHpb iJj7ECVZghviiNzWdmxQ0eay1YGCoNNtNN/3DnLSucPqsczuYHc9PlOMtXkX23vfqTGNaG9/O cc9Rp6sJ1p7N7309pta3Iw0kQ3x4x7AxelB5hap5m2SJzReo8+hQg6LSHF5zyfWv4JpkCLcg8 tzXsfgd4+hBICHLa+/8jmopjfhBAgCjIe0KYjUZSbFhyLWXNmNvcmjnhEJ1dbqHS1C3NXOGfN sxaGPvoVZeDx9hZRxjOLNLkIPUYo6i5Otocj+/ERvLduJN327qt8y408n9VXVgA+iQpZORLdU kR727oqiQVs0YtxL7CqQUcqiZkjkE/wrmPoBZlmWIgM9qMjYamVX6cWcQe2iGTMligIxfNtvS rrMf6plMpmtHJgC3c1HBxlYcSPHwY8csE0GpQRGToKqiWTIM+KDzFXEQupaAPTdJuiB2XuRbL 4+jB+QhC7YHdiszRCbQ5ANB8yUjSnuuH1Rfzo87ywMEv94L57dueTy2ZokXXa2a93s3WqOi2A BZf+RTwGaEpAIq39tm0mvq2a3tEcrJK43qoUx2k7SKR9kMTWsM8A8PvPlvegmpQV07X2M3XdD SjY7ZMaYM/DErXkF11x2z3Aj/no9Q== 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 Use inline function to replace macro since we don't need stringification. (Macro still exist until all caller get updated) And add more info about the error, and replace EIO with EUCLEAN. For nr_items error, report if it's too large or too small, and output valid value range. For node block pointer, added a new alignment checker. For key order, also output the next key to make the problem more obvious. Signed-off-by: Qu Wenruo --- fs/btrfs/tree-checker.c | 70 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 7 deletions(-) diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c index 63307e8426a6..b4ced8d3ce2a 100644 --- a/fs/btrfs/tree-checker.c +++ b/fs/btrfs/tree-checker.c @@ -38,6 +38,48 @@ btrfs_header_level(eb) == 0 ? "leaf" : "node", \ reason, btrfs_header_bytenr(eb), root->objectid, slot) +/* + * Error message should follow the format below: + * corrupt : , [, ] + * + * @type: Either leaf or node + * @identifier: The necessary info to locate the leaf/node. + * It's recommened to decode key.objecitd/offset if it's + * meaningful. + * @reason: What's wrong + * @bad_value: Optional, it's recommened to output bad value and its + * expected value (range). + * + * Since comma is used to separate the components, only SPACE is allowed + * inside each component. + */ + +/* + * Append the generic "corrupt leaf/node root=%llu block=%llu slot=%d: " to + * @fmt. + * Allowing user to customize their output. + */ +__printf(4, 5) +static void generic_err(const struct btrfs_root *root, + const struct extent_buffer *eb, + int slot, const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + btrfs_crit(root->fs_info, + "corrupt %s: root=%llu block=%llu slot=%d, %pV", + btrfs_header_level(eb) == 0 ? "leaf" : "node", + root->objectid, btrfs_header_bytenr(eb), slot, + &vaf); + va_end(args); +} + static int check_extent_data_item(struct btrfs_root *root, struct extent_buffer *leaf, struct btrfs_key *key, int slot) @@ -283,9 +325,11 @@ int btrfs_check_node(struct btrfs_root *root, struct extent_buffer *node) if (nr == 0 || nr > BTRFS_NODEPTRS_PER_BLOCK(root->fs_info)) { btrfs_crit(root->fs_info, - "corrupt node: block %llu root %llu nritems %lu", - node->start, root->objectid, nr); - return -EIO; + "corrupt node: root=%llu block=%llu, nritems too %s, have %lu expect range [1,%u]", + root->objectid, node->start, + nr == 0 ? "small" : "large", nr, + BTRFS_NODEPTRS_PER_BLOCK(root->fs_info)); + return -EUCLEAN; } for (slot = 0; slot < nr - 1; slot++) { @@ -294,14 +338,26 @@ int btrfs_check_node(struct btrfs_root *root, struct extent_buffer *node) btrfs_node_key_to_cpu(node, &next_key, slot + 1); if (!bytenr) { - CORRUPT("invalid item slot", node, root, slot); - ret = -EIO; + generic_err(root, node, slot, + "invalid NULL node pointer"); + ret = -EUCLEAN; + goto out; + } + if (!IS_ALIGNED(bytenr, root->fs_info->sectorsize)) { + generic_err(root, node, slot, + "unaligned pointer, have %llu should be aligned to %u", + bytenr, root->fs_info->sectorsize); + ret = -EUCLEAN; goto out; } if (btrfs_comp_cpu_keys(&key, &next_key) >= 0) { - CORRUPT("bad key order", node, root, slot); - ret = -EIO; + generic_err(root, node, slot, + "bad key order, current key (%llu %u %llu) next key (%llu %u %llu)", + key.objectid, key.type, key.offset, + next_key.objectid, next_key.type, + next_key.offset); + ret = -EUCLEAN; goto out; } }