mirror of
https://github.com/kdave/btrfs-progs
synced 2025-02-07 05:11:33 +00:00
btrfs-progs: update read_tree_block to take a btrfs_parent_tree_check
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> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
a38570f9d6
commit
f4e16e0238
@ -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,
|
||||
|
21
check/main.c
21
check/main.c
@ -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;
|
||||
|
||||
@ -6205,6 +6209,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;
|
||||
@ -6261,7 +6266,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;
|
||||
@ -8603,12 +8609,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 = { 0 };
|
||||
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 = { 0 };
|
||||
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"
|
||||
@ -716,14 +717,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;
|
||||
|
||||
@ -1056,7 +1059,6 @@ static int simple_quota_account_extent(struct btrfs_fs_info *info,
|
||||
struct ulist *roots = ulist_alloc(0);
|
||||
int ret;
|
||||
struct extent_buffer *node_eb;
|
||||
u64 extent_root;
|
||||
|
||||
generation = btrfs_extent_generation(leaf, ei);
|
||||
if (generation < counts.enable_gen)
|
||||
@ -1073,8 +1075,10 @@ static int simple_quota_account_extent(struct btrfs_fs_info *info,
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
extent_root = btrfs_root_id(btrfs_extent_root(info, key->objectid));
|
||||
node_eb = read_tree_block(info, key->objectid, extent_root, 0, 0, NULL);
|
||||
struct btrfs_tree_parent_check check = { 0 };
|
||||
|
||||
check.owner_root = btrfs_root_id(btrfs_extent_root(info, key->objectid));
|
||||
node_eb = read_tree_block(info, key->objectid, &check);
|
||||
if (!extent_buffer_uptodate(node_eb))
|
||||
return -EIO;
|
||||
root = btrfs_header_owner(node_eb);
|
||||
|
@ -132,6 +132,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);
|
||||
@ -145,15 +147,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;
|
||||
@ -178,9 +181,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) {
|
||||
@ -270,6 +275,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;
|
||||
|
||||
@ -290,7 +296,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;
|
||||
@ -593,12 +599,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;
|
||||
|
@ -832,6 +832,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)
|
||||
@ -842,10 +843,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) {
|
||||
|
@ -152,8 +152,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,
|
||||
@ -1687,10 +1688,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);
|
||||
|
Loading…
Reference in New Issue
Block a user