lkml.org 
[lkml]   [2018]   [Dec]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 073/101] btrfs: tree-checker: Enhance btrfs_check_node output
    Date
    4.9-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Qu Wenruo <quwenruo.btrfs@gmx.com>

    commit bba4f29896c986c4cec17bc0f19f2ce644fceae1 upstream.

    Use inline function to replace macro since we don't need
    stringification.
    (Macro still exists until all callers 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
    the 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 <quwenruo.btrfs@gmx.com>
    [ wording adjustments, unindented long strings ]
    Signed-off-by: David Sterba <dsterba@suse.com>
    [bwh: Backported to 4.9:
    - Use root->sectorsize instead of root->fs_info->sectorsize
    - BTRFS_NODEPTRS_PER_BLOCK() takes a root instead of an fs_info]
    Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    fs/btrfs/tree-checker.c | 68 +++++++++++++++++++++++++++++++++++++++++++-----
    1 file changed, 61 insertions(+), 7 deletions(-)

    --- a/fs/btrfs/tree-checker.c
    +++ b/fs/btrfs/tree-checker.c
    @@ -37,6 +37,46 @@
    btrfs_header_level(eb) == 0 ? "leaf" : "node", \
    reason, btrfs_header_bytenr(eb), root->objectid, slot)

    +/*
    + * Error message should follow the following format:
    + * corrupt <type>: <identifier>, <reason>[, <bad_value>]
    + *
    + * @type: 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: describe the error
    + * @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 generic "corrupt leaf/node root=%llu block=%llu slot=%d: " to @fmt.
    + * Allows callers to customize the 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 +322,11 @@ int btrfs_check_node(struct btrfs_root *

    if (nr == 0 || nr > BTRFS_NODEPTRS_PER_BLOCK(root)) {
    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));
    + return -EUCLEAN;
    }

    for (slot = 0; slot < nr - 1; slot++) {
    @@ -293,14 +335,26 @@ int btrfs_check_node(struct btrfs_root *
    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->sectorsize)) {
    + generic_err(root, node, slot,
    + "unaligned pointer, have %llu should be aligned to %u",
    + bytenr, root->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 (%llu %u %llu) next (%llu %u %llu)",
    + key.objectid, key.type, key.offset,
    + next_key.objectid, next_key.type,
    + next_key.offset);
    + ret = -EUCLEAN;
    goto out;
    }
    }

    \
     
     \ /
      Last update: 2018-12-06 15:49    [W:4.177 / U:0.168 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site