From patchwork Fri Sep 29 01:36:59 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qu Wenruo X-Patchwork-Id: 9977005 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 01D3D60365 for ; Fri, 29 Sep 2017 01:37:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E802F297AF for ; Fri, 29 Sep 2017 01:37:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DAED3297B1; Fri, 29 Sep 2017 01:37:49 +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.4 required=2.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_HI,RCVD_IN_SORBS_SPAM 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 59B6F297AF for ; Fri, 29 Sep 2017 01:37:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751580AbdI2Bhr (ORCPT ); Thu, 28 Sep 2017 21:37:47 -0400 Received: from mout.gmx.net ([212.227.17.22]:57646 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751490AbdI2Bhq (ORCPT ); Thu, 28 Sep 2017 21:37:46 -0400 Received: from localhost.localdomain ([45.32.39.184]) by mail.gmx.com (mrgmx101 [212.227.17.174]) with ESMTPSA (Nemesis) id 0MFgxF-1e9YUF2FGf-00EfNH; Fri, 29 Sep 2017 03:37:11 +0200 From: Qu Wenruo To: linux-btrfs@vger.kernel.org Cc: dsterba@suse.cz, nborisov@suse.com Subject: [PATCH v2 2/5] btrfs: tree-checker: Enhance btrfs_check_node output Date: Fri, 29 Sep 2017 10:36:59 +0900 Message-Id: <20170929013702.17814-3-quwenruo.btrfs@gmx.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20170929013702.17814-1-quwenruo.btrfs@gmx.com> References: <20170929013702.17814-1-quwenruo.btrfs@gmx.com> X-Provags-ID: V03:K0:SDMkz/ZDfZJB58L0g3407l2MQb1dzi41irB75Pia+rxxoWqDxR4 2lbBP236S/RcjQyk+67DEShp7bijb7J516FP+efRy0issHz3GLBDqqqLSFK4QxapJ5Nl+MI OURYyUlFxhMq7a4oo9y0e0pO4tetpkNjuPpm6lCGlI7QE/UF8ERjo7+4CEqn3oT1eOsASz4 F7knN3SL1Y7IEtiZ+U2Zw== X-UI-Out-Filterresults: notjunk:1; V01:K0:OP1XMrXCwgQ=:yONR803ywuMOw1DHytzCNY fGZ2ldoJX+DI47FwJGLQBgBCL6wzqnNUTayLY2chyOXurncP4Z3q+twdvcBWnu4W7EPTazHh8 VrUYUIH9jbvh7zMEl5/fbTgo+zpLTKnysINhq+OB2Utk2bs6mPyaZreAvvF7MIWlHmBHgzjOx zUeECMnXx/npC9ybieV1LVl/KCJWs7PFpQQDUBA1yJVu2dnOuVxFSs06LtWy+H9u8x+r0W9If ELFxLQS61hLi+3yi0aNsI6Lgp7RPgXc6acP8xD2cc1X+I//XGaiAJiVHdEjIYHCbap5HiL8Rl hRmyPUKBP/qQDxrJLWAcqa4fJBaazKmIumJ4/6DsuJGH/rbMdCXAnEMsDkEISDraHr9sbSaG4 2hASPpZEpCaFtlQrY9i6TDlQ9Ti8d0Bh4LELJ4eKLgiOmJI08CDXO0f+FSw1ie+6ATV01P4J0 MwLDGLBKL0yINHdSYM7BvpKLPq8ngpYxxoDb/9Wq+Q1dUjKwbHVtKhDW2O/qJLj3xg1/JQGK1 Wim+J1ykPkXrHHeJqWyb7J3RymTW2S9/oRMHNMG/EM6Mhxu+ZbhzhrnOP+DY6mmyvOydRTGrk F5NB5kjI730Ut+yw/ErcX538xLl3ahdglUuA9Qc+QZ396ZNMi2DWKQoMsWiBRBVdJtVSxGng3 7dKqfQpkQpjDgPUi5x0oNcSlb4xTbnqz0PJt19SDpL7q+Lr6IPJRI5RZ1QfZt/CInPs6OkZRB avuMOsYBWL0BjAkEhYfOtuZLFYJ6fUmIECkzHKEbSx6UFDEjSxS5OYWRYM2JRV4ekAxJmcmo3 zVBtu3KpfNM2um7NCQjfBmoasAyPA== 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. For nr_items error, report if it's too large or too small, and output valid value range. For blk 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 | 65 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c index 301243a69dea..a51f2503acc4 100644 --- a/fs/btrfs/tree-checker.c +++ b/fs/btrfs/tree-checker.c @@ -37,6 +37,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) @@ -282,8 +324,10 @@ 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); + "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 -EIO; } @@ -293,13 +337,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); + generic_err(root, node, slot, + "invalid node pointer, have %llu shouldn't be 0", + bytenr); ret = -EIO; 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); + 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 = -EIO; goto out; }