summaryrefslogtreecommitdiff
path: root/debug-tree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-03-03 19:55:16 -0500
committerDavid Woodhouse <dwmw2@hera.kernel.org>2008-03-03 19:55:16 -0500
commit79599947bf7ab8720a127a90d731048189678f83 (patch)
tree4d334b8c22282f1dffc2dc5b28dd37bebbd07800 /debug-tree.c
parent6dfdeac7ec99b557e2ceace0d81f9067fcb28cbf (diff)
Add debug-tree -e to print all allocated extents, and show-blocks to graph them
Diffstat (limited to 'debug-tree.c')
-rw-r--r--debug-tree.c133
1 files changed, 117 insertions, 16 deletions
diff --git a/debug-tree.c b/debug-tree.c
index 368b8fb3..7a2d0d06 100644
--- a/debug-tree.c
+++ b/debug-tree.c
@@ -18,6 +18,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
#include <uuid/uuid.h>
#include "kerncompat.h"
#include "radix-tree.h"
@@ -26,7 +27,79 @@
#include "print-tree.h"
#include "transaction.h"
-int main(int ac, char **av) {
+static int print_usage(void)
+{
+ fprintf(stderr, "usage: debug-tree [ -e ] device\n");
+ exit(1);
+}
+
+static void print_extent_leaf(struct btrfs_root *root, struct extent_buffer *l)
+{
+ int i;
+ struct btrfs_item *item;
+ struct btrfs_extent_ref *ref;
+ struct btrfs_key key;
+ static u64 last = 0;
+ static u64 last_len = 0;
+ u32 nr = btrfs_header_nritems(l);
+ u32 type;
+
+ for (i = 0 ; i < nr ; i++) {
+ item = btrfs_item_nr(l, i);
+ btrfs_item_key_to_cpu(l, &key, i);
+ type = btrfs_key_type(&key);
+ switch (type) {
+ case BTRFS_EXTENT_ITEM_KEY:
+ last_len = key.offset;
+ last = key.objectid;
+ break;
+ case BTRFS_EXTENT_REF_KEY:
+ ref = btrfs_item_ptr(l, i, struct btrfs_extent_ref);
+ printf("%llu %llu extent back ref root %llu gen %llu "
+ "owner %llu offset %llu\n",
+ (unsigned long long)last,
+ (unsigned long long)last_len,
+ (unsigned long long)btrfs_ref_root(l, ref),
+ (unsigned long long)btrfs_ref_generation(l, ref),
+ (unsigned long long)btrfs_ref_objectid(l, ref),
+ (unsigned long long)btrfs_ref_offset(l, ref));
+ break;
+ };
+ fflush(stdout);
+ }
+}
+
+static void print_extents(struct btrfs_root *root, struct extent_buffer *eb)
+{
+ int i;
+ u32 nr;
+ u32 size;
+
+ if (!eb)
+ return;
+ if (btrfs_is_leaf(eb)) {
+ print_extent_leaf(root, eb);
+ return;
+ }
+ size = btrfs_level_size(root, btrfs_header_level(eb) - 1);
+ 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);
+ if (btrfs_is_leaf(next) &&
+ btrfs_header_level(eb) != 1)
+ BUG();
+ if (btrfs_header_level(next) !=
+ btrfs_header_level(eb) - 1)
+ BUG();
+ print_extents(root, next);
+ free_extent_buffer(next);
+ }
+}
+
+int main(int ac, char **av)
+{
struct btrfs_root *root;
struct btrfs_path path;
struct btrfs_key key;
@@ -36,20 +109,37 @@ int main(int ac, char **av) {
char uuidbuf[37];
int ret;
int slot;
+ int extent_only = 0;
- if (ac != 2) {
- fprintf(stderr, "usage: %s device\n", av[0]);
- exit(1);
- }
radix_tree_init();
- root = open_ctree(av[1], 0);
+
+ while(1) {
+ int c;
+ c = getopt(ac, av, "e");
+ if (c < 0)
+ break;
+ switch(c) {
+ case 'e':
+ extent_only = 1;
+ break;
+ default:
+ print_usage();
+ }
+ }
+ ac = ac - optind;
+ if (ac != 1)
+ print_usage();
+
+ root = open_ctree(av[optind], 0);
if (!root) {
- fprintf(stderr, "unable to open %s\n", av[1]);
+ fprintf(stderr, "unable to open %s\n", av[optind]);
exit(1);
}
- printf("root tree\n");
- btrfs_print_tree(root->fs_info->tree_root,
- root->fs_info->tree_root->node);
+ if (!extent_only) {
+ printf("root tree\n");
+ btrfs_print_tree(root->fs_info->tree_root,
+ root->fs_info->tree_root->node);
+ }
btrfs_init_path(&path);
key.offset = 0;
key.objectid = 0;
@@ -71,6 +161,8 @@ int main(int ac, char **av) {
if (btrfs_key_type(&found_key) == BTRFS_ROOT_ITEM_KEY) {
unsigned long offset;
struct extent_buffer *buf;
+ int skip = extent_only;
+
offset = btrfs_item_ptr_offset(leaf, slot);
read_extent_buffer(leaf, &ri, offset, sizeof(ri));
buf = read_tree_block(root->fs_info->tree_root,
@@ -81,18 +173,27 @@ int main(int ac, char **av) {
printf("root ");
break;
case BTRFS_EXTENT_TREE_OBJECTID:
- printf("extent tree ");
+ skip = 0;
+ if (!extent_only)
+ printf("extent tree ");
break;
}
- printf("tree %llu %u %llu\n",
- (unsigned long long)found_key.objectid,
- found_key.type,
- (unsigned long long)found_key.offset);
- btrfs_print_tree(root, buf);
+ if (!skip && !extent_only) {
+ printf("tree %llu %u %llu\n",
+ (unsigned long long)found_key.objectid,
+ found_key.type,
+ (unsigned long long)found_key.offset);
+ btrfs_print_tree(root, buf);
+ } else if (extent_only && !skip) {
+ print_extents(root, buf);
+ }
}
path.slots[0]++;
}
btrfs_release_path(root, &path);
+ if (extent_only)
+ return 0;
+
printf("total bytes %llu\n",
(unsigned long long)btrfs_super_total_bytes(&root->fs_info->super_copy));
printf("bytes used %llu\n",