@@ -29,6 +29,7 @@
#include "kernel-shared/transaction.h"
#include "kernel-shared/extent_io.h"
#include "kernel-shared/file-item.h"
+#include "kernel-shared/tree-checker.h"
#include "common/utils.h"
#include "common/help.h"
#include "common/extent-cache.h"
@@ -172,8 +173,9 @@ static void corrupt_keys(struct btrfs_trans_handle *trans,
static int corrupt_keys_in_block(struct btrfs_fs_info *fs_info, u64 bytenr)
{
struct extent_buffer *eb;
+ struct btrfs_tree_parent_check check = { 0 };
- eb = read_tree_block(fs_info, bytenr, 0, 0, 0, NULL);
+ eb = read_tree_block(fs_info, bytenr, &check);
if (!extent_buffer_uptodate(eb))
return -EIO;;
@@ -301,11 +303,14 @@ static void btrfs_corrupt_extent_tree(struct btrfs_trans_handle *trans,
for (i = 0; i < btrfs_header_nritems(eb); i++) {
struct extent_buffer *next;
+ struct btrfs_tree_parent_check check = {
+ .owner_root = btrfs_header_owner(eb),
+ .transid = btrfs_node_ptr_generation(eb, i),
+ .level = btrfs_header_level(eb) - 1,
+ };
next = read_tree_block(fs_info, btrfs_node_blockptr(eb, i),
- btrfs_header_owner(eb),
- btrfs_node_ptr_generation(eb, i),
- btrfs_header_level(eb) - 1, NULL);
+ &check);
if (!extent_buffer_uptodate(next))
continue;
btrfs_corrupt_extent_tree(trans, root, next);
@@ -860,6 +865,7 @@ static int corrupt_metadata_block(struct btrfs_fs_info *fs_info, u64 block,
char *field)
{
struct extent_buffer *eb;
+ struct btrfs_tree_parent_check check = { 0 };
enum btrfs_metadata_block_field corrupt_field;
int ret;
@@ -869,7 +875,7 @@ static int corrupt_metadata_block(struct btrfs_fs_info *fs_info, u64 block,
return -EINVAL;
}
- eb = read_tree_block(fs_info, block, 0, 0, 0, NULL);
+ eb = read_tree_block(fs_info, block, &check);
if (!extent_buffer_uptodate(eb)) {
error("couldn't read in tree block %s", field);
return -EINVAL;
@@ -25,6 +25,7 @@
#include "kernel-shared/disk-io.h"
#include "kernel-shared/volumes.h"
#include "kernel-shared/extent_io.h"
+#include "kernel-shared/tree-checker.h"
#include "common/box.h"
#include "common/utils.h"
#include "common/extent-cache.h"
@@ -200,7 +201,9 @@ int btrfs_find_root_search(struct btrfs_fs_info *fs_info,
for (offset = chunk_offset;
offset < chunk_offset + chunk_size;
offset += nodesize) {
- eb = read_tree_block(fs_info, offset, 0, 0, 0, NULL);
+ struct btrfs_tree_parent_check check = { 0 };
+
+ eb = read_tree_block(fs_info, offset, &check);
if (!eb || IS_ERR(eb))
continue;
ret = add_eb_to_result(eb, result, nodesize, filter,
@@ -1894,11 +1894,15 @@ static int walk_down_tree(struct btrfs_root *root, struct btrfs_path *path,
next = btrfs_find_tree_block(gfs_info, bytenr, gfs_info->nodesize);
if (!next || !btrfs_buffer_uptodate(next, ptr_gen, 0)) {
+ struct btrfs_tree_parent_check check = {
+ .owner_root = btrfs_header_owner(cur),
+ .transid = ptr_gen,
+ .level = *level - 1,
+ };
+
free_extent_buffer(next);
reada_walk_down(root, cur, path->slots[*level]);
- next = read_tree_block(gfs_info, bytenr,
- btrfs_header_owner(cur), ptr_gen,
- *level - 1, NULL);
+ next = read_tree_block(gfs_info, bytenr, &check);
if (!extent_buffer_uptodate(next)) {
struct btrfs_key node_key;
@@ -6196,6 +6200,7 @@ static int run_next_block(struct btrfs_root *root,
{
struct extent_buffer *buf;
struct extent_record *rec = NULL;
+ struct btrfs_tree_parent_check check = { 0 };
u64 bytenr;
u32 size;
u64 parent;
@@ -6252,7 +6257,8 @@ static int run_next_block(struct btrfs_root *root,
}
/* fixme, get the real parent transid */
- buf = read_tree_block(gfs_info, bytenr, 0, gen, 0, NULL);
+ check.transid = gen;
+ buf = read_tree_block(gfs_info, bytenr, &check);
if (!extent_buffer_uptodate(buf)) {
record_bad_block_io(extent_cache, bytenr, size);
goto out;
@@ -8586,12 +8592,15 @@ static int deal_root_from_list(struct list_head *list,
while (!list_empty(list)) {
struct root_item_record *rec;
struct extent_buffer *buf;
+ struct btrfs_tree_parent_check check = { 0 };
rec = list_entry(list->next,
struct root_item_record, list);
last = 0;
- buf = read_tree_block(gfs_info, rec->bytenr, rec->objectid, 0,
- rec->level, NULL);
+
+ check.owner_root = rec->objectid;
+ check.level = rec->level;
+ buf = read_tree_block(gfs_info, rec->bytenr, &check);
if (!extent_buffer_uptodate(buf)) {
free_extent_buffer(buf);
ret = -EIO;
@@ -29,6 +29,7 @@
#include "kernel-shared/backref.h"
#include "kernel-shared/compression.h"
#include "kernel-shared/file-item.h"
+#include "kernel-shared/tree-checker.h"
#include "common/internal.h"
#include "common/messages.h"
#include "common/utils.h"
@@ -127,11 +128,12 @@ next:
static int check_prealloc_shared_data_ref(u64 parent, u64 disk_bytenr)
{
struct extent_buffer *eb;
+ struct btrfs_tree_parent_check check = { 0 };
u32 nr;
int i;
int ret = 0;
- eb = read_tree_block(gfs_info, parent, 0, 0, 0, NULL);
+ eb = read_tree_block(gfs_info, parent, &check);
if (!extent_buffer_uptodate(eb)) {
ret = -EIO;
goto out;
@@ -1116,8 +1118,9 @@ int get_extent_item_generation(u64 bytenr, u64 *gen_ret)
if (btrfs_extent_flags(path.nodes[0], ei) &
BTRFS_EXTENT_FLAG_TREE_BLOCK) {
struct extent_buffer *eb;
+ struct btrfs_tree_parent_check check = { 0 };
- eb = read_tree_block(gfs_info, bytenr, 0, 0, 0, NULL);
+ eb = read_tree_block(gfs_info, bytenr, &check);
if (extent_buffer_uptodate(eb)) {
*gen_ret = btrfs_header_generation(eb);
ret = 0;
@@ -3684,6 +3684,7 @@ static int query_tree_block_level(u64 bytenr)
struct btrfs_path path = {};
struct btrfs_key key;
struct btrfs_extent_item *ei;
+ struct btrfs_tree_parent_check check = { 0 };
u64 flags;
u64 transid;
u8 backref_level;
@@ -3731,7 +3732,8 @@ static int query_tree_block_level(u64 bytenr)
btrfs_release_path(&path);
/* Get level from tree block as an alternative source */
- eb = read_tree_block(gfs_info, bytenr, 0, transid, 0, NULL);
+ check.transid = transid;
+ eb = read_tree_block(gfs_info, bytenr, &check);
if (!extent_buffer_uptodate(eb)) {
free_extent_buffer(eb);
return -EIO;
@@ -3760,6 +3762,9 @@ static int check_tree_block_backref(u64 root_id, u64 bytenr, int level)
struct btrfs_path path = {};
struct extent_buffer *eb;
struct extent_buffer *node;
+ struct btrfs_tree_parent_check check = {
+ .owner_root = root_id,
+ };
u32 nodesize = btrfs_super_nodesize(gfs_info->super_copy);
int err = 0;
int ret;
@@ -3783,7 +3788,7 @@ static int check_tree_block_backref(u64 root_id, u64 bytenr, int level)
}
/* Read out the tree block to get item/node key */
- eb = read_tree_block(gfs_info, bytenr, root_id, 0, 0, NULL);
+ eb = read_tree_block(gfs_info, bytenr, &check);
if (!extent_buffer_uptodate(eb)) {
err |= REFERENCER_MISSING;
free_extent_buffer(eb);
@@ -3877,11 +3882,12 @@ static int is_tree_reloc_root(struct extent_buffer *eb)
static int check_shared_block_backref(u64 parent, u64 bytenr, int level)
{
struct extent_buffer *eb;
+ struct btrfs_tree_parent_check check = { 0 };
u32 nr;
int found_parent = 0;
int i;
- eb = read_tree_block(gfs_info, parent, 0, 0, 0, NULL);
+ eb = read_tree_block(gfs_info, parent, &check);
if (!extent_buffer_uptodate(eb))
goto out;
@@ -4048,11 +4054,12 @@ static int check_shared_data_backref(u64 parent, u64 bytenr)
struct extent_buffer *eb;
struct btrfs_key key;
struct btrfs_file_extent_item *fi;
+ struct btrfs_tree_parent_check check = { 0 };
u32 nr;
int found_parent = 0;
int i;
- eb = read_tree_block(gfs_info, parent, 0, 0, 0, NULL);
+ eb = read_tree_block(gfs_info, parent, &check);
if (!extent_buffer_uptodate(eb))
goto out;
@@ -5018,11 +5025,15 @@ static int walk_down_tree(struct btrfs_root *root, struct btrfs_path *path,
next = btrfs_find_tree_block(gfs_info, bytenr, gfs_info->nodesize);
if (!next || !btrfs_buffer_uptodate(next, ptr_gen, 0)) {
+ struct btrfs_tree_parent_check check = {
+ .owner_root = btrfs_header_owner(cur),
+ .transid = ptr_gen,
+ .level = *level - 1,
+ };
+
free_extent_buffer(next);
reada_walk_down(root, cur, path->slots[*level]);
- next = read_tree_block(gfs_info, bytenr,
- btrfs_header_owner(cur),
- ptr_gen, *level - 1, NULL);
+ next = read_tree_block(gfs_info, bytenr, &check);
if (!extent_buffer_uptodate(next)) {
struct btrfs_key node_key;
@@ -30,6 +30,7 @@
#include "kernel-shared/ulist.h"
#include "kernel-shared/extent_io.h"
#include "kernel-shared/transaction.h"
+#include "kernel-shared/tree-checker.h"
#include "common/messages.h"
#include "common/rbtree-utils.h"
#include "check/repair.h"
@@ -714,14 +715,16 @@ static int travel_tree(struct btrfs_fs_info *info, struct btrfs_root *root,
{
int ret, nr, i;
struct extent_buffer *eb;
+ struct btrfs_tree_parent_check check = {
+ .owner_root = btrfs_root_id(root),
+ };
u64 new_bytenr;
u64 new_num_bytes;
// printf("travel_tree: bytenr: %llu\tnum_bytes: %llu\tref_parent: %llu\n",
// bytenr, num_bytes, ref_parent);
- eb = read_tree_block(info, bytenr, btrfs_root_id(root), 0,
- 0, NULL);
+ eb = read_tree_block(info, bytenr, &check);
if (!extent_buffer_uptodate(eb))
return -EIO;
@@ -137,6 +137,8 @@ static int traverse_tree_blocks(struct extent_io_tree *tree,
nritems = btrfs_header_nritems(eb);
for (i = 0; i < nritems; i++) {
+ struct btrfs_tree_parent_check check = { 0 };
+
if (level == 0) {
bool is_extent_root;
btrfs_item_key_to_cpu(eb, &key, i);
@@ -150,15 +152,16 @@ static int traverse_tree_blocks(struct extent_io_tree *tree,
ri = btrfs_item_ptr(eb, i, struct btrfs_root_item);
bytenr = btrfs_disk_root_bytenr(eb, ri);
+ check.owner_root = key.objectid;
+ check.level = btrfs_disk_root_level(eb, ri);
+
/*
* If at any point we start needing the real root we
* will have to build a stump root for the root we are
* in, but for now this doesn't actually use the root so
* just pass in extent_root.
*/
- tmp = read_tree_block(fs_info, bytenr, key.objectid, 0,
- btrfs_disk_root_level(eb, ri),
- NULL);
+ tmp = read_tree_block(fs_info, bytenr, &check);
if (!extent_buffer_uptodate(tmp)) {
fprintf(stderr, "Error reading root block\n");
return -EIO;
@@ -183,9 +186,10 @@ static int traverse_tree_blocks(struct extent_io_tree *tree,
continue;
}
- tmp = read_tree_block(fs_info, bytenr,
- btrfs_header_owner(eb), 0,
- level - 1, NULL);
+ check.owner_root = btrfs_header_owner(eb);
+ check.level = level - 1;
+
+ tmp = read_tree_block(fs_info, bytenr, &check);
if (!extent_buffer_uptodate(tmp)) {
fprintf(stderr, "Error reading tree block\n");
return -EIO;
@@ -32,6 +32,7 @@
#include "kernel-shared/print-tree.h"
#include "kernel-shared/volumes.h"
#include "kernel-shared/extent_io.h"
+#include "kernel-shared/tree-checker.h"
#include "common/defs.h"
#include "common/extent-cache.h"
#include "common/messages.h"
@@ -58,10 +59,14 @@ static void print_extents(struct extent_buffer *eb)
nr = btrfs_header_nritems(eb);
for (i = 0; i < nr; i++) {
+ struct btrfs_tree_parent_check check = {
+ .owner_root = btrfs_header_owner(eb),
+ .transid = btrfs_node_ptr_generation(eb, i),
+ .level = btrfs_header_level(eb) - 1,
+ };
+
next = read_tree_block(fs_info, btrfs_node_blockptr(eb, i),
- btrfs_header_owner(eb),
- btrfs_node_ptr_generation(eb, i),
- btrfs_header_level(eb) - 1, NULL);
+ &check);
if (!extent_buffer_uptodate(next))
continue;
if (btrfs_is_leaf(next) && btrfs_header_level(eb) != 1) {
@@ -269,6 +274,7 @@ static int dump_print_tree_blocks(struct btrfs_fs_info *fs_info,
{
struct cache_extent *ce;
struct extent_buffer *eb;
+ struct btrfs_tree_parent_check check = { 0 };
u64 bytenr;
int ret = 0;
@@ -289,7 +295,7 @@ static int dump_print_tree_blocks(struct btrfs_fs_info *fs_info,
goto next;
}
- eb = read_tree_block(fs_info, bytenr, 0, 0, 0, NULL);
+ eb = read_tree_block(fs_info, bytenr, &check);
if (!extent_buffer_uptodate(eb)) {
error("failed to read tree block %llu", bytenr);
ret = -EIO;
@@ -592,12 +598,14 @@ again:
if (found_key.type == BTRFS_ROOT_ITEM_KEY) {
unsigned long offset;
struct extent_buffer *buf;
+ struct btrfs_tree_parent_check check = {
+ .owner_root = key.objectid,
+ };
bool skip = (extent_only || device_only || uuid_tree_only);
offset = btrfs_item_ptr_offset(leaf, slot);
read_extent_buffer(leaf, &ri, offset, sizeof(ri));
- buf = read_tree_block(info, btrfs_root_bytenr(&ri),
- key.objectid, 0, 0, NULL);
+ buf = read_tree_block(info, btrfs_root_bytenr(&ri), &check);
if (!extent_buffer_uptodate(buf))
goto next;
if (tree_id && found_key.objectid != tree_id) {
@@ -29,6 +29,7 @@
#include "kernel-shared/disk-io.h"
#include "kernel-shared/extent_io.h"
#include "kernel-shared/file-item.h"
+#include "kernel-shared/tree-checker.h"
#include "common/utils.h"
#include "common/help.h"
#include "common/messages.h"
@@ -152,10 +153,12 @@ static int walk_nodes(struct btrfs_root *root, struct btrfs_path *path,
path->slots[level] = i;
if ((level - 1) > 0 || find_inline) {
- tmp = read_tree_block(root->fs_info, cur_blocknr,
- btrfs_header_owner(b),
- btrfs_node_ptr_generation(b, i),
- level - 1, NULL);
+ struct btrfs_tree_parent_check check = {
+ .owner_root = btrfs_header_owner(b),
+ .transid = btrfs_node_ptr_generation(b, i),
+ .level = level - 1,
+ };
+ tmp = read_tree_block(root->fs_info, cur_blocknr, &check);
if (!extent_buffer_uptodate(tmp)) {
error("failed to read blocknr %llu",
btrfs_node_blockptr(b, i));
@@ -45,6 +45,7 @@
#include "kernel-shared/extent_io.h"
#include "kernel-shared/compression.h"
#include "kernel-shared/file-item.h"
+#include "kernel-shared/tree-checker.h"
#include "common/utils.h"
#include "common/help.h"
#include "common/open-utils.h"
@@ -1241,15 +1242,17 @@ static struct btrfs_root *open_fs(const char *dev, u64 root_location,
* the fs_root.
*/
if (!extent_buffer_uptodate(fs_info->tree_root->node)) {
+ struct btrfs_tree_parent_check check = { 0 };
u64 generation;
root = fs_info->tree_root;
if (!root_location)
root_location = btrfs_super_root(fs_info->super_copy);
generation = btrfs_super_generation(fs_info->super_copy);
- root->node = read_tree_block(fs_info, root_location,
- btrfs_root_id(root), generation,
- 0, NULL);
+
+ check.owner_root = btrfs_root_id(root);
+ check.transid = generation;
+ root->node = read_tree_block(fs_info, root_location, &check);
if (!extent_buffer_uptodate(root->node)) {
error("opening tree root failed");
close_ctree(root);
@@ -1514,9 +1517,9 @@ static int cmd_restore(const struct cmd_struct *cmd, int argc, char **argv)
goto out;
if (fs_location != 0) {
+ struct btrfs_tree_parent_check check = { 0 };
free_extent_buffer(root->node);
- root->node = read_tree_block(root->fs_info, fs_location, 0, 0,
- 0, NULL);
+ root->node = read_tree_block(root->fs_info, fs_location, &check);
if (!extent_buffer_uptodate(root->node)) {
error("failed to read fs location");
ret = 1;
@@ -21,6 +21,7 @@
#include "kernel-shared/file-item.h"
#include "kernel-shared/disk-io.h"
#include "kernel-shared/volumes.h"
+#include "kernel-shared/tree-checker.h"
#include "crypto/crc32c.h"
#include "common/internal.h"
#include "common/messages.h"
@@ -437,11 +438,11 @@ static int flush_pending(struct metadump_struct *md, int done)
}
while (!md->data && size > 0) {
+ struct btrfs_tree_parent_check check = { 0 };
u64 this_read = min((u64)md->root->fs_info->nodesize,
size);
- eb = read_tree_block(md->root->fs_info, start, 0, 0, 0,
- NULL);
+ eb = read_tree_block(md->root->fs_info, start, &check);
if (!extent_buffer_uptodate(eb)) {
free(async->buffer);
free(async);
@@ -510,6 +511,7 @@ static int copy_tree_blocks(struct btrfs_root *root, struct extent_buffer *eb,
struct btrfs_root_item *ri;
struct btrfs_key key;
struct btrfs_fs_info *fs_info = root->fs_info;
+ struct btrfs_tree_parent_check check = { 0 };
u64 bytenr;
int level;
int nritems = 0;
@@ -545,7 +547,7 @@ static int copy_tree_blocks(struct btrfs_root *root, struct extent_buffer *eb,
continue;
ri = btrfs_item_ptr(eb, i, struct btrfs_root_item);
bytenr = btrfs_disk_root_bytenr(eb, ri);
- tmp = read_tree_block(fs_info, bytenr, 0, 0, 0, NULL);
+ tmp = read_tree_block(fs_info, bytenr, &check);
if (!extent_buffer_uptodate(tmp)) {
error("unable to read log root block");
return -EIO;
@@ -556,7 +558,7 @@ static int copy_tree_blocks(struct btrfs_root *root, struct extent_buffer *eb,
return ret;
} else {
bytenr = btrfs_node_blockptr(eb, i);
- tmp = read_tree_block(fs_info, bytenr, 0, 0, 0, NULL);
+ tmp = read_tree_block(fs_info, bytenr, &check);
if (!extent_buffer_uptodate(tmp)) {
error("unable to read log root block");
return -EIO;
@@ -20,6 +20,7 @@
#include "kernel-shared/disk-io.h"
#include "kernel-shared/volumes.h"
#include "kernel-shared/transaction.h"
+#include "kernel-shared/tree-checker.h"
#include "common/internal.h"
#include "common/messages.h"
#include "common/open-utils.h"
@@ -1366,6 +1367,7 @@ static int iter_tree_blocks(struct btrfs_fs_info *fs_info,
struct extent_buffer *eb, bool pin)
{
void (*func)(struct btrfs_fs_info *fs_info, u64 bytenr, u64 num_bytes);
+ struct btrfs_tree_parent_check check = { 0 };
int nritems;
int level;
int i;
@@ -1396,7 +1398,7 @@ static int iter_tree_blocks(struct btrfs_fs_info *fs_info,
continue;
ri = btrfs_item_ptr(eb, i, struct btrfs_root_item);
bytenr = btrfs_disk_root_bytenr(eb, ri);
- tmp = read_tree_block(fs_info, bytenr, 0, 0, 0, NULL);
+ tmp = read_tree_block(fs_info, bytenr, &check);
if (!extent_buffer_uptodate(tmp)) {
error("unable to read log root block");
return -EIO;
@@ -1407,7 +1409,7 @@ static int iter_tree_blocks(struct btrfs_fs_info *fs_info,
return ret;
} else {
bytenr = btrfs_node_blockptr(eb, i);
- tmp = read_tree_block(fs_info, bytenr, 0, 0, 0, NULL);
+ tmp = read_tree_block(fs_info, bytenr, &check);
if (!extent_buffer_uptodate(tmp)) {
error("unable to read log root block");
return -EIO;
@@ -41,6 +41,7 @@
#include "kernel-shared/volumes.h"
#include "kernel-shared/extent_io.h"
#include "kernel-shared/file-item.h"
+#include "kernel-shared/tree-checker.h"
#include "crypto/crc32c.h"
#include "crypto/hash.h"
#include "common/internal.h"
@@ -23,6 +23,7 @@
#include "kernel-shared/ulist.h"
#include "kernel-shared/transaction.h"
#include "kernel-shared/messages.h"
+#include "kernel-shared/tree-checker.h"
#include "common/internal.h"
#define pr_debug(...) do { } while (0)
@@ -454,6 +455,7 @@ static int __add_missing_keys(struct btrfs_fs_info *fs_info,
while (!list_empty(&prefstate->pending_missing_keys)) {
struct __prelim_ref *ref;
+ struct btrfs_tree_parent_check check;
ref = list_first_pref(&prefstate->pending_missing_keys);
@@ -461,8 +463,13 @@ static int __add_missing_keys(struct btrfs_fs_info *fs_info,
ASSERT(!ref->parent);
ASSERT(!ref->key_for_search.type);
BUG_ON(!ref->wanted_disk_byte);
- eb = read_tree_block(fs_info, ref->wanted_disk_byte,
- ref->root_id, 0, ref->level - 1, NULL);
+
+ check.owner_root = ref->root_id;
+ check.transid = 0;
+ check.has_first_key = false;
+ check.level = ref->level - 1;
+
+ eb = read_tree_block(fs_info, ref->wanted_disk_byte, &check);
if (!extent_buffer_uptodate(eb)) {
free_extent_buffer(eb);
return -EIO;
@@ -823,9 +830,11 @@ static int find_parent_nodes(struct btrfs_trans_handle *trans,
if (extent_item_pos && !ref->inode_list &&
ref->level == 0) {
struct extent_buffer *eb;
+ struct btrfs_tree_parent_check check = {
+ .level = ref->level,
+ };
- eb = read_tree_block(fs_info, ref->parent, 0,
- 0, ref->level, NULL);
+ eb = read_tree_block(fs_info, ref->parent, &check);
if (!extent_buffer_uptodate(eb)) {
free_extent_buffer(eb);
ret = -EIO;
@@ -715,6 +715,7 @@ struct extent_buffer *btrfs_read_node_slot(struct extent_buffer *parent,
{
struct btrfs_fs_info *fs_info = parent->fs_info;
struct extent_buffer *ret;
+ struct btrfs_tree_parent_check check = { 0 };
int level = btrfs_header_level(parent);
if (slot < 0)
@@ -725,10 +726,12 @@ struct extent_buffer *btrfs_read_node_slot(struct extent_buffer *parent,
if (level == 0)
return NULL;
+ check.owner_root = btrfs_header_owner(parent);
+ check.transid = btrfs_node_ptr_generation(parent, slot);
+ check.level = level - 1;
+
ret = read_tree_block(fs_info, btrfs_node_blockptr(parent, slot),
- btrfs_header_owner(parent),
- btrfs_node_ptr_generation(parent, slot),
- level - 1, NULL);
+ &check);
if (!extent_buffer_uptodate(ret))
return ERR_PTR(-EIO);
@@ -417,23 +417,12 @@ int btrfs_read_extent_buffer(struct extent_buffer *eb,
}
struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr,
- u64 owner_root, u64 parent_transid,
- int level, struct btrfs_key *first_key)
+ struct btrfs_tree_parent_check *check)
{
- struct btrfs_tree_parent_check check = {
- .owner_root = owner_root,
- .transid = parent_transid,
- .level = level,
- };
int ret;
struct extent_buffer *eb;
u32 sectorsize = fs_info->sectorsize;
- if (first_key) {
- check.has_first_key = true;
- memcpy(&check.first_key, first_key, sizeof(*first_key));
- }
-
/*
* Don't even try to create tree block for unaligned tree block
* bytenr.
@@ -450,10 +439,10 @@ struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr,
if (!eb)
return ERR_PTR(-ENOMEM);
- if (btrfs_buffer_uptodate(eb, parent_transid, 0))
+ if (btrfs_buffer_uptodate(eb, check->transid, 0))
return eb;
- ret = btrfs_read_extent_buffer(eb, &check);
+ ret = btrfs_read_extent_buffer(eb, check);
if (ret) {
/*
* We failed to read this tree block, it be should deleted right
@@ -508,8 +497,13 @@ static int read_root_node(struct btrfs_fs_info *fs_info,
struct btrfs_root *root, u64 bytenr, u64 gen,
int level)
{
- root->node = read_tree_block(fs_info, bytenr, btrfs_root_id(root),
- gen, level, NULL);
+ struct btrfs_tree_parent_check check = {
+ .owner_root = btrfs_root_id(root),
+ .transid = gen,
+ .level = level,
+ };
+
+ root->node = read_tree_block(fs_info, bytenr, &check);
if (!extent_buffer_uptodate(root->node))
goto err;
if (btrfs_header_level(root->node) != level) {
@@ -147,8 +147,7 @@ struct btrfs_device;
int read_whole_eb(struct btrfs_fs_info *info, struct extent_buffer *eb, int mirror);
struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr,
- u64 owner_root, u64 parent_transid,
- int level, struct btrfs_key *first_key);
+ struct btrfs_tree_parent_check *check);
void readahead_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr,
u64 parent_transid);
@@ -28,6 +28,7 @@
#include "kernel-shared/compression.h"
#include "kernel-shared/accessors.h"
#include "kernel-shared/file-item.h"
+#include "kernel-shared/tree-checker.h"
#include "common/utils.h"
static void print_dir_item_type(struct extent_buffer *eb,
@@ -1613,10 +1614,13 @@ static void dfs_print_children(struct extent_buffer *root_eb, unsigned int mode)
mode &= ~(BTRFS_PRINT_TREE_BFS);
for (i = 0; i < nr; i++) {
+ struct btrfs_tree_parent_check check = {
+ .owner_root = btrfs_header_owner(root_eb),
+ .transid = btrfs_node_ptr_generation(root_eb, i),
+ .level = root_eb_level,
+ };
next = read_tree_block(fs_info, btrfs_node_blockptr(root_eb, i),
- btrfs_header_owner(root_eb),
- btrfs_node_ptr_generation(root_eb, i),
- root_eb_level, NULL);
+ &check);
if (!extent_buffer_uptodate(next)) {
fprintf(stderr, "failed to read %llu in tree %llu\n",
btrfs_node_blockptr(root_eb, i),
@@ -24,6 +24,7 @@
#include "kernel-shared/disk-io.h"
#include "kernel-shared/extent_io.h"
#include "kernel-shared/volumes.h"
+#include "kernel-shared/tree-checker.h"
#include "common/defs.h"
#include "common/messages.h"
#include "tune/tune.h"
@@ -97,6 +98,7 @@ static int change_extent_tree_uuid(struct btrfs_fs_info *fs_info, uuid_t new_fsi
while (1) {
struct btrfs_extent_item *ei;
struct extent_buffer *eb;
+ struct btrfs_tree_parent_check check = { 0 };
u64 flags;
u64 bytenr;
@@ -111,7 +113,7 @@ static int change_extent_tree_uuid(struct btrfs_fs_info *fs_info, uuid_t new_fsi
goto next;
bytenr = key.objectid;
- eb = read_tree_block(fs_info, bytenr, 0, 0, 0, NULL);
+ eb = read_tree_block(fs_info, bytenr, &check);
if (IS_ERR(eb)) {
error("failed to read tree block: %llu", bytenr);
ret = PTR_ERR(eb);
In the kernel we've added a control struct to handle the different checks we want to do on extent buffers when we read them. Update our copy of read_tree_block to take this as an argument, then update all of the callers to use the new structure. Signed-off-by: Josef Bacik <josef@toxicpanda.com> --- btrfs-corrupt-block.c | 16 +++++++++++----- btrfs-find-root.c | 5 ++++- check/main.c | 21 +++++++++++++++------ check/mode-common.c | 7 +++++-- check/mode-lowmem.c | 25 ++++++++++++++++++------- check/qgroup-verify.c | 7 +++++-- check/repair.c | 16 ++++++++++------ cmds/inspect-dump-tree.c | 20 ++++++++++++++------ cmds/inspect-tree-stats.c | 11 +++++++---- cmds/restore.c | 13 ++++++++----- image/image-create.c | 10 ++++++---- image/image-restore.c | 6 ++++-- image/main.c | 1 + kernel-shared/backref.c | 17 +++++++++++++---- kernel-shared/ctree.c | 9 ++++++--- kernel-shared/disk-io.c | 26 ++++++++++---------------- kernel-shared/disk-io.h | 3 +-- kernel-shared/print-tree.c | 10 +++++++--- tune/change-uuid.c | 4 +++- 19 files changed, 148 insertions(+), 79 deletions(-)