88c602ab44
Btrfs doesn't check whether the tree block respects the root owner. This means, if a tree block referred by a parent in extent tree, but has owner of 5, btrfs can still continue reading the tree block, as long as it doesn't trigger other sanity checks. Normally this is fine, but combined with the empty tree check in check_leaf(), if we hit an empty extent tree, but the root node has csum tree owner, we can let such extent buffer to sneak in. Shrink the hole by: - Do extra eb owner check at tree read time - Make sure the root owner extent buffer exactly matches the root id. Unfortunately we can't yet completely patch the hole, there are several call sites can't pass all info we need: - For reloc/log trees Their owner is key::offset, not key::objectid. We need the full root key to do that accurate check. For now, we just skip the ownership check for those trees. - For add_data_references() of relocation That call site doesn't have any parent/ownership info, as all the bytenrs are all from btrfs_find_all_leafs(). - For direct backref items walk Direct backref items records the parent bytenr directly, thus unlike indirect backref item, we don't do a full tree search. Thus in that case, we don't have full parent owner to check. For the later two cases, they all pass 0 as @owner_root, thus we can skip those cases if @owner_root is 0. Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
31 lines
776 B
C
31 lines
776 B
C
/* 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 "ctree.h"
|
|
#include "extent_io.h"
|
|
|
|
/*
|
|
* Comprehensive leaf checker.
|
|
* Will check not only the item pointers, but also every possible member
|
|
* in item data.
|
|
*/
|
|
int btrfs_check_leaf_full(struct extent_buffer *leaf);
|
|
|
|
/*
|
|
* Less strict leaf checker.
|
|
* Will only check item pointers, not reading item data.
|
|
*/
|
|
int btrfs_check_leaf_relaxed(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);
|
|
|
|
#endif
|