From patchwork Fri Sep 29 06:48:46 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qu Wenruo X-Patchwork-Id: 9977127 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 49B1160365 for ; Fri, 29 Sep 2017 06:49:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3C18629761 for ; Fri, 29 Sep 2017 06:49:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 309472976B; Fri, 29 Sep 2017 06:49:09 +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 A664429761 for ; Fri, 29 Sep 2017 06:49:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751994AbdI2GtG (ORCPT ); Fri, 29 Sep 2017 02:49:06 -0400 Received: from mout.gmx.net ([212.227.17.20]:51979 "EHLO mout.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750899AbdI2GtF (ORCPT ); Fri, 29 Sep 2017 02:49:05 -0400 Received: from localhost.localdomain ([104.207.157.105]) by mail.gmx.com (mrgmx101 [212.227.17.174]) with ESMTPSA (Nemesis) id 0LgdBZ-1daI851PxF-00nzny; Fri, 29 Sep 2017 08:48:56 +0200 From: Qu Wenruo To: linux-btrfs@vger.kernel.org Cc: dsterba@suse.cz, nborisov@suse.com Subject: [PATCH v3 2/5] btrfs: tree-checker: Enhance btrfs_check_node output Date: Fri, 29 Sep 2017 06:48:46 +0000 Message-Id: <20170929064849.15086-3-quwenruo.btrfs@gmx.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20170929064849.15086-1-quwenruo.btrfs@gmx.com> References: <20170929064849.15086-1-quwenruo.btrfs@gmx.com> X-Provags-ID: V03:K0:avzH9Csfjlhry5t7wTi2xaUxrYJlzA++DJs0Ei1baYsCO/BGm/H DFCUXtCewyletN8NRPso7wlR9p25zv2ChNwHEMGxxQtwfs/PPamXmo8AgGA1+RMGLmEUg8Y nw8iweaWVPZahLlHRbOrD0S4w+tlMSNN+LBDQN2+aTp+ttpgbLyH59Brqx5/UyuB1H3dLv4 eZZkY0uZQlZAVMGqp3gjA== X-UI-Out-Filterresults: notjunk:1; V01:K0:RD0ceU1HckY=:wnXPve/9CVAEm2EGkR+K0N V1J7KsIkl7VTcZow8aEQDP/vstX9CPV2GrROjf7BTglA+WyvuwNZMSWv7LH0dJHM8USUv8PCm NMPcW/+O2yUhlNiHcSDOopNkYtaj4sKsxuJB4ekaAv6BUUFm2ojsiBcI+Do8PDXc9IkWTDzEi 8HxFkmMi5Elo8MUQoy4BC1HWn/a7eWAYsdbTFKENZwSe/QvAu6dmS1ilXl30iixGuQHcSA6KS OgsPtZ2wdLl+lWxGN1j3h16nJjVmaW2Oq0mbjRrYbVAdMRW9cAUuaoLxMsCV0Ie1v/+EzvDnq vsypWFPq8ozM2vGN9lURdmwD5Fe/A5gIAlMIcHhzRM7pmFjXPtlkAcRfZ6ICLWcp4WDIZ/syE T8qB2pBRJegiUhej1H8yRFMFsZEMjrumTsqGMY8s/zKRxeS5L8h9IDGaAqOa2niU6HzHHcV7U Jxdt/j+uBhptuSqET4Mk5Q4VAa4xLV5cBLvesaietsi/ijLX+FH7Iul8ErxoF+FrTe6bmrDqA AQEDXmQWBJhPXT7kvqawK+Z8vGBvsvQ7+y3ZebyIOGTv4iOuGNN4voqYPG7BsG2E3WanCiRiT PIQ7O06bm29pUX27LUXOjFXacneIwrn0Vq8nFr2viOsxYyxTWHVK7wWhStk47+TdEBPm1rcZM VaF5delOmU8VEhVeZ/benq8gixvkGbySPBB7Bh5+fxHC3wY5V74/Ij4ofJEgXA6bV4dVNMfDt Kwq3Z741VRt9canvx2Xw4LAMoQFpDpF3AZ+a22jxP8OOvEZ4UkPtWclg226X9O/Jj1kA+Dyr5 cll7+4P3jKWnNhy90mYOCkB9JTgZQ== 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 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 | 71 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 7 deletions(-) diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c index 301243a69dea..94acf3f5d6fd 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,9 +324,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++) { @@ -293,14 +337,27 @@ 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 node pointer, have %llu shouldn't be 0", + bytenr); + 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; } }