btrfs: Move btrfs_check_chunk_valid() to tree-check.[ch] and export it
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>
This commit is contained in:
parent
90b1377daa
commit
82fc28fbed
|
@ -448,6 +448,103 @@ static int check_block_group_item(struct btrfs_fs_info *fs_info,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
* Common point to switch the item-specific validation.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -25,4 +25,8 @@ int btrfs_check_leaf_relaxed(struct btrfs_fs_info *fs_info,
|
||||||
struct extent_buffer *leaf);
|
struct extent_buffer *leaf);
|
||||||
int btrfs_check_node(struct btrfs_fs_info *fs_info, struct extent_buffer *node);
|
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
|
#endif
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
#include "dev-replace.h"
|
#include "dev-replace.h"
|
||||||
#include "sysfs.h"
|
#include "sysfs.h"
|
||||||
|
#include "tree-checker.h"
|
||||||
|
|
||||||
const struct btrfs_raid_attr btrfs_raid_array[BTRFS_NR_RAID_TYPES] = {
|
const struct btrfs_raid_attr btrfs_raid_array[BTRFS_NR_RAID_TYPES] = {
|
||||||
[BTRFS_RAID_RAID10] = {
|
[BTRFS_RAID_RAID10] = {
|
||||||
|
@ -6714,99 +6715,6 @@ struct btrfs_device *btrfs_alloc_device(struct btrfs_fs_info *fs_info,
|
||||||
return dev;
|
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,
|
static void btrfs_report_missing_device(struct btrfs_fs_info *fs_info,
|
||||||
u64 devid, u8 *uuid, bool error)
|
u64 devid, u8 *uuid, bool error)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue