btrfs-progs: check: introduce function to check inode item
[platform/upstream/btrfs-progs.git] / cmds-inspect-dump-tree.c
index 5e20634..03aa0b2 100644 (file)
@@ -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",
                                                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;
        }