diff options
Diffstat (limited to 'cmds-inspect-dump-tree.c')
-rw-r--r-- | cmds-inspect-dump-tree.c | 71 |
1 files changed, 44 insertions, 27 deletions
diff --git a/cmds-inspect-dump-tree.c b/cmds-inspect-dump-tree.c index 5e206345..df7be617 100644 --- a/cmds-inspect-dump-tree.c +++ b/cmds-inspect-dump-tree.c @@ -35,6 +35,7 @@ static void print_extents(struct btrfs_root *root, struct extent_buffer *eb) { + struct extent_buffer *next; int i; u32 nr; u32 size; @@ -50,21 +51,32 @@ static void print_extents(struct btrfs_root *root, struct extent_buffer *eb) size = root->nodesize; nr = btrfs_header_nritems(eb); for (i = 0; i < nr; i++) { - struct extent_buffer *next = read_tree_block(root, - btrfs_node_blockptr(eb, i), - size, - btrfs_node_ptr_generation(eb, i)); + next = read_tree_block(root, btrfs_node_blockptr(eb, i), + size, btrfs_node_ptr_generation(eb, i)); if (!extent_buffer_uptodate(next)) continue; - if (btrfs_is_leaf(next) && - btrfs_header_level(eb) != 1) - BUG(); - if (btrfs_header_level(next) != - btrfs_header_level(eb) - 1) - BUG(); + if (btrfs_is_leaf(next) && btrfs_header_level(eb) != 1) { + warning( + "eb corrupted: item %d eb level %d next level %d, skipping the rest", + i, btrfs_header_level(next), + btrfs_header_level(eb)); + goto out; + } + if (btrfs_header_level(next) != btrfs_header_level(eb) - 1) { + warning( + "eb corrupted: item %d eb level %d next level %d, skipping the rest", + i, btrfs_header_level(next), + btrfs_header_level(eb)); + goto out; + } print_extents(root, next); free_extent_buffer(next); } + + return; + +out: + free_extent_buffer(next); } static void print_old_roots(struct btrfs_super_block *super) @@ -248,26 +260,27 @@ int cmd_inspect_dump_tree(int argc, char **argv) case 'b': block_only = arg_strtou64(optarg); break; - case 't': - if (string_is_numerical(optarg)) { - tree_id = arg_strtou64(optarg); - } else { - const char *end = NULL; + case 't': { + const char *end = NULL; + if (string_is_numerical(optarg)) + tree_id = arg_strtou64(optarg); + else tree_id = treeid_from_string(optarg, &end); - if (*end) { - error("unexpected tree id suffix of '%s': %s\n", - optarg, end); - exit(1); - } - } if (!tree_id) { - error("unrecognized tree id: %s\n", + error("unrecognized tree id: %s", optarg); exit(1); } + + if (end && *end) { + error("unexpected tree id suffix of '%s': %s", + optarg, end); + exit(1); + } break; + } default: usage(cmd_inspect_dump_tree_usage); } @@ -376,9 +389,14 @@ again: key.offset = 0; key.objectid = 0; - btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); + key.type = BTRFS_ROOT_ITEM_KEY; ret = btrfs_search_slot(NULL, tree_root_scan, &key, &path, 0, 0); - BUG_ON(ret < 0); + if (ret < 0) { + error("cannot read ROOT_ITEM from tree %llu: %s", + (unsigned long long)tree_root_scan->root_key.objectid, + strerror(-ret)); + goto close_root; + } while (1) { leaf = path.nodes[0]; slot = path.slots[0]; @@ -391,7 +409,7 @@ again: } btrfs_item_key(leaf, &disk_key, path.slots[0]); btrfs_disk_key_to_cpu(&found_key, &disk_key); - if (btrfs_key_type(&found_key) == BTRFS_ROOT_ITEM_KEY) { + if (found_key.type == BTRFS_ROOT_ITEM_KEY) { unsigned long offset; struct extent_buffer *buf; int skip = extent_only | device_only | uuid_tree_only; @@ -525,8 +543,7 @@ next: no_node: btrfs_release_path(&path); - if (tree_root_scan == info->tree_root && - info->log_root_tree) { + if (tree_root_scan == info->tree_root && info->log_root_tree) { tree_root_scan = info->log_root_tree; goto again; } |