btrfs-progs: sync tree-checker.[ch] from kernel

This syncs tree-checker.c from the kernel.  The main modification was to
add a open ctree flag to skip the deeper leaf checks, and plumbing this
through tree-checker.c.  We need this for things like fsck or
btrfs-image that need to work with slightly corrupted file systems, and
these checks simply make us unable to look at the corrupted blocks.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Josef Bacik 2023-04-19 17:24:09 -04:00 committed by David Sterba
parent 180bd5edd1
commit e150c843ea
16 changed files with 2186 additions and 304 deletions

View file

@ -187,6 +187,7 @@ objects = \
kernel-shared/print-tree.o \
kernel-shared/root-tree.o \
kernel-shared/transaction.o \
kernel-shared/tree-checker.o \
kernel-shared/ulist.o \
kernel-shared/uuid-tree.o \
kernel-shared/volumes.o \

View file

@ -44,6 +44,7 @@
#include "kernel-shared/backref.h"
#include "kernel-shared/ulist.h"
#include "kernel-shared/file-item.h"
#include "kernel-shared/tree-checker.h"
#include "common/defs.h"
#include "common/extent-cache.h"
#include "common/internal.h"
@ -9999,7 +10000,8 @@ static int cmd_check(const struct cmd_struct *cmd, int argc, char **argv)
int qgroups_repaired = 0;
int qgroup_verify_ret;
unsigned ctree_flags = OPEN_CTREE_EXCLUSIVE |
OPEN_CTREE_ALLOW_TRANSID_MISMATCH;
OPEN_CTREE_ALLOW_TRANSID_MISMATCH |
OPEN_CTREE_SKIP_LEAF_ITEM_CHECKS;
int force = 0;
while(1) {

View file

@ -31,6 +31,7 @@
#include "kernel-shared/compression.h"
#include "kernel-shared/volumes.h"
#include "kernel-shared/file-item.h"
#include "kernel-shared/tree-checker.h"
#include "common/messages.h"
#include "common/internal.h"
#include "common/utils.h"

View file

@ -27,6 +27,7 @@
#include "kernel-shared/transaction.h"
#include "kernel-shared/extent_io.h"
#include "kernel-shared/disk-io.h"
#include "kernel-shared/tree-checker.h"
#include "common/extent-cache.h"
#include "check/repair.h"

View file

@ -1025,7 +1025,8 @@ static int create_metadump(const char *input, FILE *out, int num_threads,
int ret;
int err = 0;
root = open_ctree(input, 0, OPEN_CTREE_ALLOW_TRANSID_MISMATCH);
root = open_ctree(input, 0, OPEN_CTREE_ALLOW_TRANSID_MISMATCH |
OPEN_CTREE_SKIP_LEAF_ITEM_CHECKS);
if (!root) {
error("open ctree failed");
return -EIO;
@ -2798,7 +2799,7 @@ static int restore_metadump(const char *input, FILE *out, int old_restore,
ocf.filename = target;
ocf.flags = OPEN_CTREE_WRITES | OPEN_CTREE_RESTORE |
OPEN_CTREE_PARTIAL;
OPEN_CTREE_PARTIAL | OPEN_CTREE_SKIP_LEAF_ITEM_CHECKS;
info = open_ctree_fs_info(&ocf);
if (!info) {
error("open ctree failed");
@ -2864,7 +2865,8 @@ static int restore_metadump(const char *input, FILE *out, int old_restore,
OPEN_CTREE_PARTIAL |
OPEN_CTREE_WRITES |
OPEN_CTREE_NO_DEVICES |
OPEN_CTREE_ALLOW_TRANSID_MISMATCH);
OPEN_CTREE_ALLOW_TRANSID_MISMATCH |
OPEN_CTREE_SKIP_LEAF_ITEM_CHECKS);
if (!root) {
error("open ctree failed in %s", target);
ret = -EIO;
@ -2883,7 +2885,8 @@ static int restore_metadump(const char *input, FILE *out, int old_restore,
if (!info) {
root = open_ctree_fd(fileno(out), target, 0,
OPEN_CTREE_ALLOW_TRANSID_MISMATCH);
OPEN_CTREE_ALLOW_TRANSID_MISMATCH |
OPEN_CTREE_SKIP_LEAF_ITEM_CHECKS);
if (!root) {
error("open ctree failed in %s", target);
ret = -EIO;
@ -3226,7 +3229,8 @@ int BOX_MAIN(image)(int argc, char *argv[])
int i;
ocf.filename = target;
ocf.flags = OPEN_CTREE_PARTIAL | OPEN_CTREE_RESTORE;
ocf.flags = OPEN_CTREE_PARTIAL | OPEN_CTREE_RESTORE |
OPEN_CTREE_SKIP_LEAF_ITEM_CHECKS;
info = open_ctree_fs_info(&ocf);
if (!info) {
error("open ctree failed at %s", target);

View file

@ -85,6 +85,7 @@
#define _RET_IP_ 0
#define TASK_UNINTERRUPTIBLE 0
#define SLAB_MEM_SPREAD 0
#define ALLOW_ERROR_INJECTION(a, b)
#ifndef ULONG_MAX
#define ULONG_MAX (~0UL)
@ -417,6 +418,15 @@ do { \
__ret_warn_on; \
})
#define WARN(c, msg...) ({ \
int __ret_warn_on = !!(c); \
if (__ret_warn_on) \
printf(msg); \
__ret_warn_on; \
})
#define IS_ENABLED(c) 0
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})

View file

@ -1,6 +1,7 @@
#ifndef _PERF_LINUX_BITOPS_H_
#define _PERF_LINUX_BITOPS_H_
#include "kerncompat.h"
#include <endian.h>
#include "common/internal.h"

View file

@ -22,6 +22,8 @@
#ifndef __BTRFS_PROGS_RAID56_H__
#define __BTRFS_PROGS_RAID56_H__
#include "kerncompat.h"
void raid6_gen_syndrome(int disks, size_t bytes, void **ptrs);
int raid5_gen_result(int nr_devs, size_t stripe_len, int dest, void **data);

View file

@ -16,17 +16,18 @@
* Boston, MA 021110-1307, USA.
*/
#include "kernel-lib/bitops.h"
#include "kernel-lib/sizes.h"
#include "kernel-shared/ctree.h"
#include "kernel-shared/disk-io.h"
#include "kernel-shared/transaction.h"
#include "kernel-shared/print-tree.h"
#include "kernel-lib/bitops.h"
#include "kernel-shared/tree-checker.h"
#include "kernel-shared/volumes.h"
#include "crypto/crc32c.h"
#include "common/internal.h"
#include "common/messages.h"
#include "common/utils.h"
#include "kernel-lib/sizes.h"
#include "kernel-shared/volumes.h"
#include "check/repair.h"
static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
@ -602,185 +603,6 @@ static inline unsigned int leaf_data_end(const struct extent_buffer *leaf)
return btrfs_item_offset(leaf, nr - 1);
}
static void generic_err(const struct extent_buffer *buf, int slot,
const char *fmt, ...)
{
va_list args;
fprintf(stderr, "corrupt %s: root=%lld block=%llu slot=%d, ",
btrfs_header_level(buf) == 0 ? "leaf": "node",
btrfs_header_owner(buf), btrfs_header_bytenr(buf), slot);
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
fprintf(stderr, "\n");
}
enum btrfs_tree_block_status __btrfs_check_node(struct extent_buffer *node)
{
struct btrfs_fs_info *fs_info = node->fs_info;
unsigned long nr = btrfs_header_nritems(node);
struct btrfs_key key, next_key;
int slot;
int level = btrfs_header_level(node);
u64 bytenr;
enum btrfs_tree_block_status ret = BTRFS_TREE_BLOCK_INVALID_NRITEMS;
if (level <= 0 || level >= BTRFS_MAX_LEVEL) {
generic_err(node, 0,
"invalid level for node, have %d expect [1, %d]",
level, BTRFS_MAX_LEVEL - 1);
ret = BTRFS_TREE_BLOCK_INVALID_LEVEL;
goto fail;
}
if (nr == 0 || nr > BTRFS_NODEPTRS_PER_BLOCK(fs_info)) {
generic_err(node, 0,
"corrupt node: root=%llu block=%llu, nritems too %s, have %lu expect range [1,%u]",
btrfs_header_owner(node), node->start,
nr == 0 ? "small" : "large", nr,
BTRFS_NODEPTRS_PER_BLOCK(fs_info));
ret = BTRFS_TREE_BLOCK_INVALID_NRITEMS;
goto fail;
}
for (slot = 0; slot < nr - 1; slot++) {
bytenr = btrfs_node_blockptr(node, slot);
btrfs_node_key_to_cpu(node, &key, slot);
btrfs_node_key_to_cpu(node, &next_key, slot + 1);
if (!bytenr) {
generic_err(node, slot,
"invalid NULL node pointer");
ret = BTRFS_TREE_BLOCK_INVALID_BLOCKPTR;
goto fail;
}
if (!IS_ALIGNED(bytenr, fs_info->sectorsize)) {
generic_err(node, slot,
"unaligned pointer, have %llu should be aligned to %u",
bytenr, fs_info->sectorsize);
ret = BTRFS_TREE_BLOCK_INVALID_BLOCKPTR;
goto fail;
}
if (btrfs_comp_cpu_keys(&key, &next_key) >= 0) {
generic_err(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 = BTRFS_TREE_BLOCK_BAD_KEY_ORDER;
goto fail;
}
}
ret = BTRFS_TREE_BLOCK_CLEAN;
fail:
return ret;
}
enum btrfs_tree_block_status __btrfs_check_leaf(struct extent_buffer *leaf)
{
struct btrfs_fs_info *fs_info = leaf->fs_info;
/* No valid key type is 0, so all key should be larger than this key */
struct btrfs_key prev_key = {0, 0, 0};
struct btrfs_key key;
u32 nritems = btrfs_header_nritems(leaf);
int slot;
int ret;
if (btrfs_header_level(leaf) != 0) {
generic_err(leaf, 0,
"invalid level for leaf, have %d expect 0",
btrfs_header_level(leaf));
ret = BTRFS_TREE_BLOCK_INVALID_LEVEL;
goto fail;
}
if (nritems == 0)
return 0;
/*
* Check the following things to make sure this is a good leaf, and
* leaf users won't need to bother with similar sanity checks:
*
* 1) key ordering
* 2) item offset and size
* No overlap, no hole, all inside the leaf.
* 3) item content
* If possible, do comprehensive sanity check.
* NOTE: All checks must only rely on the item data itself.
*/
for (slot = 0; slot < nritems; slot++) {
u32 item_end_expected;
u64 item_data_end;
btrfs_item_key_to_cpu(leaf, &key, slot);
/* Make sure the keys are in the right order */
if (btrfs_comp_cpu_keys(&prev_key, &key) >= 0) {
generic_err(leaf, slot,
"bad key order, prev (%llu %u %llu) current (%llu %u %llu)",
prev_key.objectid, prev_key.type,
prev_key.offset, key.objectid, key.type,
key.offset);
ret = BTRFS_TREE_BLOCK_BAD_KEY_ORDER;
goto fail;
}
item_data_end = (u64)btrfs_item_offset(leaf, slot) +
btrfs_item_size(leaf, slot);
/*
* Make sure the offset and ends are right, remember that the
* item data starts at the end of the leaf and grows towards the
* front.
*/
if (slot == 0)
item_end_expected = BTRFS_LEAF_DATA_SIZE(fs_info);
else
item_end_expected = btrfs_item_offset(leaf,
slot - 1);
if (item_data_end != item_end_expected) {
generic_err(leaf, slot,
"unexpected item end, have %llu expect %u",
item_data_end, item_end_expected);
ret = BTRFS_TREE_BLOCK_INVALID_OFFSETS;
goto fail;
}
/*
* Check to make sure that we don't point outside of the leaf,
* just in case all the items are consistent to each other, but
* all point outside of the leaf.
*/
if (item_data_end > BTRFS_LEAF_DATA_SIZE(fs_info)) {
generic_err(leaf, slot,
"slot end outside of leaf, have %llu expect range [0, %u]",
item_data_end, BTRFS_LEAF_DATA_SIZE(fs_info));
ret = BTRFS_TREE_BLOCK_INVALID_OFFSETS;
goto fail;
}
/* Also check if the item pointer overlaps with btrfs item. */
if (btrfs_item_ptr_offset(leaf, slot) <
btrfs_item_nr_offset(leaf, slot) + sizeof(struct btrfs_item)) {
generic_err(leaf, slot,
"slot overlaps with its data, item end %lu data start %lu",
btrfs_item_nr_offset(leaf, slot) +
sizeof(struct btrfs_item),
btrfs_item_ptr_offset(leaf, slot));
ret = BTRFS_TREE_BLOCK_INVALID_OFFSETS;
goto fail;
}
prev_key.objectid = key.objectid;
prev_key.type = key.type;
prev_key.offset = key.offset;
}
ret = BTRFS_TREE_BLOCK_CLEAN;
fail:
return ret;
}
static int noinline check_block(struct btrfs_fs_info *fs_info,
struct btrfs_path *path, int level)
{

View file

@ -185,17 +185,6 @@ struct btrfs_path {
sizeof(struct btrfs_item))
#define BTRFS_MAX_EXTENT_SIZE 128UL * 1024 * 1024
enum btrfs_tree_block_status {
BTRFS_TREE_BLOCK_CLEAN,
BTRFS_TREE_BLOCK_INVALID_NRITEMS,
BTRFS_TREE_BLOCK_INVALID_PARENT_KEY,
BTRFS_TREE_BLOCK_BAD_KEY_ORDER,
BTRFS_TREE_BLOCK_INVALID_LEVEL,
BTRFS_TREE_BLOCK_INVALID_FREE_SPACE,
BTRFS_TREE_BLOCK_INVALID_OFFSETS,
BTRFS_TREE_BLOCK_INVALID_BLOCKPTR,
};
/*
* We don't want to overwrite 1M at the beginning of device, even though
* there is our 1st superblock at 64k. Some possible reasons:
@ -373,6 +362,7 @@ struct btrfs_fs_info {
unsigned int finalize_on_close:1;
unsigned int hide_names:1;
unsigned int allow_transid_mismatch:1;
unsigned int skip_leaf_item_checks:1;
int transaction_aborted;
int force_csum_type;
@ -958,8 +948,6 @@ int btrfs_convert_one_bg(struct btrfs_trans_handle *trans, u64 bytenr);
int btrfs_comp_cpu_keys(const struct btrfs_key *k1, const struct btrfs_key *k2);
int btrfs_del_ptr(struct btrfs_root *root, struct btrfs_path *path,
int level, int slot);
enum btrfs_tree_block_status __btrfs_check_node(struct extent_buffer *buf);
enum btrfs_tree_block_status __btrfs_check_leaf(struct extent_buffer *buf);
struct extent_buffer *read_node_slot(struct btrfs_fs_info *fs_info,
struct extent_buffer *parent, int slot);
int btrfs_previous_item(struct btrfs_root *root,

View file

@ -24,19 +24,20 @@
#include <unistd.h>
#include <uuid/uuid.h>
#include "kerncompat.h"
#include "kernel-lib/bitops.h"
#include "kernel-shared/ctree.h"
#include "kernel-shared/disk-io.h"
#include "kernel-shared/volumes.h"
#include "kernel-shared/transaction.h"
#include "zoned.h"
#include "kernel-shared/tree-checker.h"
#include "kernel-shared/zoned.h"
#include "kernel-shared/print-tree.h"
#include "crypto/hash.h"
#include "crypto/crc32c.h"
#include "common/utils.h"
#include "kernel-shared/print-tree.h"
#include "kernel-lib/bitops.h"
#include "common/rbtree-utils.h"
#include "common/device-scan.h"
#include "common/device-utils.h"
#include "crypto/hash.h"
/* specified errno for check_tree_block */
#define BTRFS_BAD_BYTENR (-1)
@ -1503,6 +1504,8 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, struct open_ctree_flags *oc
fs_info->hide_names = 1;
if (flags & OPEN_CTREE_ALLOW_TRANSID_MISMATCH)
fs_info->allow_transid_mismatch = 1;
if (flags & OPEN_CTREE_SKIP_LEAF_ITEM_CHECKS)
fs_info->skip_leaf_item_checks = 1;
if ((flags & OPEN_CTREE_RECOVER_SUPER)
&& (flags & OPEN_CTREE_TEMPORARY_SUPER)) {

View file

@ -98,6 +98,12 @@ enum btrfs_open_ctree_flags {
* stored in the csum tree during conversion.
*/
OPEN_CTREE_SKIP_CSUM_CHECK = (1U << 16),
/*
* Allow certain commands like check/restore to ignore more structure
* specific checks and only do the superficial checks.
*/
OPEN_CTREE_SKIP_LEAF_ITEM_CHECKS = (1U << 17),
};
/*

2064
kernel-shared/tree-checker.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,73 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) Qu Wenruo 2017. All rights reserved.
*/
#ifndef BTRFS_TREE_CHECKER_H
#define BTRFS_TREE_CHECKER_H
#include "kerncompat.h"
#include "uapi/btrfs_tree.h"
struct extent_buffer;
struct btrfs_chunk;
/* All the extra info needed to verify the parentness of a tree block. */
struct btrfs_tree_parent_check {
/*
* The owner check against the tree block.
*
* Can be 0 to skip the owner check.
*/
u64 owner_root;
/*
* Expected transid, can be 0 to skip the check, but such skip
* should only be utlized for backref walk related code.
*/
u64 transid;
/*
* The expected first key.
*
* This check can be skipped if @has_first_key is false, such skip
* can happen for case where we don't have the parent node key,
* e.g. reading the tree root, doing backref walk.
*/
struct btrfs_key first_key;
bool has_first_key;
/* The expected level. Should always be set. */
u8 level;
};
enum btrfs_tree_block_status {
BTRFS_TREE_BLOCK_CLEAN,
BTRFS_TREE_BLOCK_INVALID_NRITEMS,
BTRFS_TREE_BLOCK_INVALID_PARENT_KEY,
BTRFS_TREE_BLOCK_BAD_KEY_ORDER,
BTRFS_TREE_BLOCK_INVALID_LEVEL,
BTRFS_TREE_BLOCK_INVALID_FREE_SPACE,
BTRFS_TREE_BLOCK_INVALID_OFFSETS,
BTRFS_TREE_BLOCK_INVALID_BLOCKPTR,
BTRFS_TREE_BLOCK_INVALID_ITEM,
BTRFS_TREE_BLOCK_INVALID_OWNER,
};
/*
* Exported simply for btrfs-progs which wants to have the
* btrfs_tree_block_status return codes.
*/
enum btrfs_tree_block_status __btrfs_check_leaf(struct extent_buffer *leaf);
enum btrfs_tree_block_status __btrfs_check_node(struct extent_buffer *node);
int btrfs_check_leaf(struct extent_buffer *leaf);
int btrfs_check_node(struct extent_buffer *node);
int btrfs_check_chunk_valid(struct extent_buffer *leaf,
struct btrfs_chunk *chunk, u64 logical);
int btrfs_check_eb_owner(const struct extent_buffer *eb, u64 root_owner);
int btrfs_verify_level_key(struct extent_buffer *eb, int level,
struct btrfs_key *first_key, u64 parent_transid);
#endif

View file

@ -23,15 +23,16 @@
#include <uuid/uuid.h>
#include <fcntl.h>
#include <unistd.h>
#include "kernel-lib/raid56.h"
#include "kernel-shared/ctree.h"
#include "kernel-shared/disk-io.h"
#include "kernel-shared/transaction.h"
#include "kernel-shared/print-tree.h"
#include "kernel-shared/volumes.h"
#include "zoned.h"
#include "kernel-shared/tree-checker.h"
#include "kernel-shared/zoned.h"
#include "common/utils.h"
#include "common/device-utils.h"
#include "kernel-lib/raid56.h"
const struct btrfs_raid_attr btrfs_raid_array[BTRFS_NR_RAID_TYPES] = {
[BTRFS_RAID_RAID10] = {
@ -2086,101 +2087,6 @@ static struct btrfs_device *fill_missing_device(u64 devid)
return device;
}
/*
* slot == -1: SYSTEM chunk
* return -EIO on error, otherwise return 0
*/
int btrfs_check_chunk_valid(struct extent_buffer *leaf,
struct btrfs_chunk *chunk, u64 logical)
{
struct btrfs_fs_info *fs_info = leaf->fs_info;
u64 length;
u64 stripe_len;
u16 num_stripes;
u16 sub_stripes;
u64 type;
u32 sectorsize = fs_info->sectorsize;
int min_devs;
int table_sub_stripes;
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 == 0) {
error("invalid num_stripes, have %u expect non-zero",
num_stripes);
return -EUCLEAN;
}
/*
* These valid checks may be insufficient to cover every corner cases.
*/
if (!IS_ALIGNED(logical, sectorsize)) {
error("invalid chunk logical %llu", logical);
return -EIO;
}
if (btrfs_chunk_sector_size(leaf, chunk) != sectorsize) {
error("invalid chunk sectorsize %llu",
(unsigned long long)btrfs_chunk_sector_size(leaf, chunk));
return -EIO;
}
if (!length || !IS_ALIGNED(length, sectorsize)) {
error("invalid chunk length %llu", length);
return -EIO;
}
if (stripe_len != BTRFS_STRIPE_LEN) {
error("invalid chunk stripe length: %llu", stripe_len);
return -EIO;
}
if (type & ~(BTRFS_BLOCK_GROUP_TYPE_MASK |
BTRFS_BLOCK_GROUP_PROFILE_MASK)) {
error("unrecognized chunk type: %llu",
~(BTRFS_BLOCK_GROUP_TYPE_MASK |
BTRFS_BLOCK_GROUP_PROFILE_MASK) & type);
return -EIO;
}
if (!(type & BTRFS_BLOCK_GROUP_TYPE_MASK)) {
error("missing chunk type flag: %llu", type);
return -EIO;
}
if (!(is_power_of_2(type & BTRFS_BLOCK_GROUP_PROFILE_MASK) ||
(type & BTRFS_BLOCK_GROUP_PROFILE_MASK) == 0)) {
error("conflicting chunk type detected: %llu", type);
return -EIO;
}
if ((type & BTRFS_BLOCK_GROUP_PROFILE_MASK) &&
!is_power_of_2(type & BTRFS_BLOCK_GROUP_PROFILE_MASK)) {
error("conflicting chunk profile detected: %llu", type);
return -EIO;
}
/*
* Device number check against profile
*/
min_devs = btrfs_bg_type_to_devs_min(type);
table_sub_stripes = btrfs_bg_type_to_sub_stripes(type);
if ((type & BTRFS_BLOCK_GROUP_RAID10 && (sub_stripes != table_sub_stripes ||
!IS_ALIGNED(num_stripes, sub_stripes))) ||
(type & BTRFS_BLOCK_GROUP_RAID1 && num_stripes < min_devs) ||
(type & BTRFS_BLOCK_GROUP_RAID1C3 && num_stripes < min_devs) ||
(type & BTRFS_BLOCK_GROUP_RAID1C4 && num_stripes < min_devs) ||
(type & BTRFS_BLOCK_GROUP_RAID5 && num_stripes < min_devs) ||
(type & BTRFS_BLOCK_GROUP_RAID6 && num_stripes < min_devs) ||
(type & BTRFS_BLOCK_GROUP_DUP && num_stripes > 2) ||
((type & BTRFS_BLOCK_GROUP_PROFILE_MASK) == 0 &&
num_stripes != 1)) {
error("Invalid num_stripes:sub_stripes %u:%u for profile %llu",
num_stripes, sub_stripes,
type & BTRFS_BLOCK_GROUP_PROFILE_MASK);
return -EIO;
}
return 0;
}
/*
* Slot is used to verify the chunk item is valid
*

View file

@ -294,8 +294,6 @@ int write_raid56_with_parity(struct btrfs_fs_info *info,
struct extent_buffer *eb,
struct btrfs_multi_bio *multi,
u64 stripe_len, u64 *raid_map);
int btrfs_check_chunk_valid(struct extent_buffer *leaf,
struct btrfs_chunk *chunk, u64 logical);
u64 btrfs_stripe_length(struct btrfs_fs_info *fs_info,
struct extent_buffer *leaf,
struct btrfs_chunk *chunk);