lkml.org 
[lkml]   [2020]   [Nov]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 22/71] btrfs: Move btrfs_check_chunk_valid() to tree-check.[ch] and export it
    Date
    From: Qu Wenruo <wqu@suse.com>

    commit 82fc28fbedbb59642f05215db3b0ef4eb91aa31d upstream.

    By function, chunk item verification is more suitable to be done inside
    tree-checker.

    So move btrfs_check_chunk_valid() to tree-checker.c and export it.

    And since it's now moved to tree-checker, also add a better comment for
    what this function is doing.

    Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
    Signed-off-by: Qu Wenruo <wqu@suse.com>
    Reviewed-by: David Sterba <dsterba@suse.com>
    Signed-off-by: David Sterba <dsterba@suse.com>
    [bwh: Cherry-picked for 4.19 to ease backporting later fixes]
    Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    fs/btrfs/tree-checker.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++
    fs/btrfs/tree-checker.h | 4 +
    fs/btrfs/volumes.c | 94 ----------------------------------------------
    3 files changed, 102 insertions(+), 93 deletions(-)

    --- a/fs/btrfs/tree-checker.c
    +++ b/fs/btrfs/tree-checker.c
    @@ -449,6 +449,103 @@ static int check_block_group_item(struct
    }

    /*
    + * The common chunk check which could also work on super block sys chunk array.
    + *
    + * Return -EIO if anything is corrupted.
    + * Return 0 if everything is OK.
    + */
    +int btrfs_check_chunk_valid(struct btrfs_fs_info *fs_info,
    + struct extent_buffer *leaf,
    + struct btrfs_chunk *chunk, u64 logical)
    +{
    + u64 length;
    + u64 stripe_len;
    + u16 num_stripes;
    + u16 sub_stripes;
    + u64 type;
    + u64 features;
    + bool mixed = false;
    +
    + length = btrfs_chunk_length(leaf, chunk);
    + stripe_len = btrfs_chunk_stripe_len(leaf, chunk);
    + num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
    + sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk);
    + type = btrfs_chunk_type(leaf, chunk);
    +
    + if (!num_stripes) {
    + btrfs_err(fs_info, "invalid chunk num_stripes: %u",
    + num_stripes);
    + return -EIO;
    + }
    + if (!IS_ALIGNED(logical, fs_info->sectorsize)) {
    + btrfs_err(fs_info, "invalid chunk logical %llu", logical);
    + return -EIO;
    + }
    + if (btrfs_chunk_sector_size(leaf, chunk) != fs_info->sectorsize) {
    + btrfs_err(fs_info, "invalid chunk sectorsize %u",
    + btrfs_chunk_sector_size(leaf, chunk));
    + return -EIO;
    + }
    + if (!length || !IS_ALIGNED(length, fs_info->sectorsize)) {
    + btrfs_err(fs_info, "invalid chunk length %llu", length);
    + return -EIO;
    + }
    + if (!is_power_of_2(stripe_len) || stripe_len != BTRFS_STRIPE_LEN) {
    + btrfs_err(fs_info, "invalid chunk stripe length: %llu",
    + stripe_len);
    + return -EIO;
    + }
    + if (~(BTRFS_BLOCK_GROUP_TYPE_MASK | BTRFS_BLOCK_GROUP_PROFILE_MASK) &
    + type) {
    + btrfs_err(fs_info, "unrecognized chunk type: %llu",
    + ~(BTRFS_BLOCK_GROUP_TYPE_MASK |
    + BTRFS_BLOCK_GROUP_PROFILE_MASK) &
    + btrfs_chunk_type(leaf, chunk));
    + return -EIO;
    + }
    +
    + if ((type & BTRFS_BLOCK_GROUP_TYPE_MASK) == 0) {
    + btrfs_err(fs_info, "missing chunk type flag: 0x%llx", type);
    + return -EIO;
    + }
    +
    + if ((type & BTRFS_BLOCK_GROUP_SYSTEM) &&
    + (type & (BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA))) {
    + btrfs_err(fs_info,
    + "system chunk with data or metadata type: 0x%llx", type);
    + return -EIO;
    + }
    +
    + features = btrfs_super_incompat_flags(fs_info->super_copy);
    + if (features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS)
    + mixed = true;
    +
    + if (!mixed) {
    + if ((type & BTRFS_BLOCK_GROUP_METADATA) &&
    + (type & BTRFS_BLOCK_GROUP_DATA)) {
    + btrfs_err(fs_info,
    + "mixed chunk type in non-mixed mode: 0x%llx", type);
    + return -EIO;
    + }
    + }
    +
    + if ((type & BTRFS_BLOCK_GROUP_RAID10 && sub_stripes != 2) ||
    + (type & BTRFS_BLOCK_GROUP_RAID1 && num_stripes != 2) ||
    + (type & BTRFS_BLOCK_GROUP_RAID5 && num_stripes < 2) ||
    + (type & BTRFS_BLOCK_GROUP_RAID6 && num_stripes < 3) ||
    + (type & BTRFS_BLOCK_GROUP_DUP && num_stripes != 2) ||
    + ((type & BTRFS_BLOCK_GROUP_PROFILE_MASK) == 0 && num_stripes != 1)) {
    + btrfs_err(fs_info,
    + "invalid num_stripes:sub_stripes %u:%u for profile %llu",
    + num_stripes, sub_stripes,
    + type & BTRFS_BLOCK_GROUP_PROFILE_MASK);
    + return -EIO;
    + }
    +
    + return 0;
    +}
    +
    +/*
    * Common point to switch the item-specific validation.
    */
    static int check_leaf_item(struct btrfs_fs_info *fs_info,
    --- a/fs/btrfs/tree-checker.h
    +++ b/fs/btrfs/tree-checker.h
    @@ -25,4 +25,8 @@ int btrfs_check_leaf_relaxed(struct btrf
    struct extent_buffer *leaf);
    int btrfs_check_node(struct btrfs_fs_info *fs_info, struct extent_buffer *node);

    +int btrfs_check_chunk_valid(struct btrfs_fs_info *fs_info,
    + struct extent_buffer *leaf,
    + struct btrfs_chunk *chunk, u64 logical);
    +
    #endif
    --- a/fs/btrfs/volumes.c
    +++ b/fs/btrfs/volumes.c
    @@ -28,6 +28,7 @@
    #include "math.h"
    #include "dev-replace.h"
    #include "sysfs.h"
    +#include "tree-checker.h"

    const struct btrfs_raid_attr btrfs_raid_array[BTRFS_NR_RAID_TYPES] = {
    [BTRFS_RAID_RAID10] = {
    @@ -6370,99 +6371,6 @@ struct btrfs_device *btrfs_alloc_device(
    return dev;
    }

    -/* Return -EIO if any error, otherwise return 0. */
    -static int btrfs_check_chunk_valid(struct btrfs_fs_info *fs_info,
    - struct extent_buffer *leaf,
    - struct btrfs_chunk *chunk, u64 logical)
    -{
    - u64 length;
    - u64 stripe_len;
    - u16 num_stripes;
    - u16 sub_stripes;
    - u64 type;
    - u64 features;
    - bool mixed = false;
    -
    - length = btrfs_chunk_length(leaf, chunk);
    - stripe_len = btrfs_chunk_stripe_len(leaf, chunk);
    - num_stripes = btrfs_chunk_num_stripes(leaf, chunk);
    - sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk);
    - type = btrfs_chunk_type(leaf, chunk);
    -
    - if (!num_stripes) {
    - btrfs_err(fs_info, "invalid chunk num_stripes: %u",
    - num_stripes);
    - return -EIO;
    - }
    - if (!IS_ALIGNED(logical, fs_info->sectorsize)) {
    - btrfs_err(fs_info, "invalid chunk logical %llu", logical);
    - return -EIO;
    - }
    - if (btrfs_chunk_sector_size(leaf, chunk) != fs_info->sectorsize) {
    - btrfs_err(fs_info, "invalid chunk sectorsize %u",
    - btrfs_chunk_sector_size(leaf, chunk));
    - return -EIO;
    - }
    - if (!length || !IS_ALIGNED(length, fs_info->sectorsize)) {
    - btrfs_err(fs_info, "invalid chunk length %llu", length);
    - return -EIO;
    - }
    - if (!is_power_of_2(stripe_len) || stripe_len != BTRFS_STRIPE_LEN) {
    - btrfs_err(fs_info, "invalid chunk stripe length: %llu",
    - stripe_len);
    - return -EIO;
    - }
    - if (~(BTRFS_BLOCK_GROUP_TYPE_MASK | BTRFS_BLOCK_GROUP_PROFILE_MASK) &
    - type) {
    - btrfs_err(fs_info, "unrecognized chunk type: %llu",
    - ~(BTRFS_BLOCK_GROUP_TYPE_MASK |
    - BTRFS_BLOCK_GROUP_PROFILE_MASK) &
    - btrfs_chunk_type(leaf, chunk));
    - return -EIO;
    - }
    -
    - if ((type & BTRFS_BLOCK_GROUP_TYPE_MASK) == 0) {
    - btrfs_err(fs_info, "missing chunk type flag: 0x%llx", type);
    - return -EIO;
    - }
    -
    - if ((type & BTRFS_BLOCK_GROUP_SYSTEM) &&
    - (type & (BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA))) {
    - btrfs_err(fs_info,
    - "system chunk with data or metadata type: 0x%llx", type);
    - return -EIO;
    - }
    -
    - features = btrfs_super_incompat_flags(fs_info->super_copy);
    - if (features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS)
    - mixed = true;
    -
    - if (!mixed) {
    - if ((type & BTRFS_BLOCK_GROUP_METADATA) &&
    - (type & BTRFS_BLOCK_GROUP_DATA)) {
    - btrfs_err(fs_info,
    - "mixed chunk type in non-mixed mode: 0x%llx", type);
    - return -EIO;
    - }
    - }
    -
    - if ((type & BTRFS_BLOCK_GROUP_RAID10 && sub_stripes != 2) ||
    - (type & BTRFS_BLOCK_GROUP_RAID1 && num_stripes != 2) ||
    - (type & BTRFS_BLOCK_GROUP_RAID5 && num_stripes < 2) ||
    - (type & BTRFS_BLOCK_GROUP_RAID6 && num_stripes < 3) ||
    - (type & BTRFS_BLOCK_GROUP_DUP && num_stripes != 2) ||
    - ((type & BTRFS_BLOCK_GROUP_PROFILE_MASK) == 0 &&
    - num_stripes != 1)) {
    - btrfs_err(fs_info,
    - "invalid num_stripes:sub_stripes %u:%u for profile %llu",
    - num_stripes, sub_stripes,
    - type & BTRFS_BLOCK_GROUP_PROFILE_MASK);
    - return -EIO;
    - }
    -
    - return 0;
    -}
    -
    static void btrfs_report_missing_device(struct btrfs_fs_info *fs_info,
    u64 devid, u8 *uuid, bool error)
    {

    \
     
     \ /
      Last update: 2020-11-09 14:09    [W:4.742 / U:0.332 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site