1 #include <stdio.h> 2 #include <stdlib.h> 3 #include "kerncompat.h" 4 #include "radix-tree.h" 5 #include "ctree.h" 6 #include "disk-io.h" 7 8 void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l) 9 { 10 int i; 11 u32 nr = btrfs_header_nritems(&l->header); 12 struct btrfs_item *item; 13 struct btrfs_extent_item *ei; 14 struct btrfs_root_item *ri; 15 struct btrfs_dir_item *di; 16 u32 type; 17 u32 namelen; 18 19 printf("leaf %Lu total ptrs %d free space %d\n", 20 btrfs_header_blocknr(&l->header), nr, 21 btrfs_leaf_free_space(root, l)); 22 fflush(stdout); 23 for (i = 0 ; i < nr ; i++) { 24 item = l->items + i; 25 type = btrfs_disk_key_type(&item->key); 26 printf("\titem %d key (%Lu %u %Lu) itemoff %d itemsize %d\n", 27 i, 28 btrfs_disk_key_objectid(&item->key), 29 btrfs_disk_key_flags(&item->key), 30 btrfs_disk_key_offset(&item->key), 31 btrfs_item_offset(item), 32 btrfs_item_size(item)); 33 switch (type) { 34 case BTRFS_INODE_ITEM_KEY: 35 break; 36 case BTRFS_DIR_ITEM_KEY: 37 namelen = btrfs_item_size(l->items + i) - sizeof(*di); 38 di = btrfs_item_ptr(l, i, struct btrfs_dir_item); 39 printf("\t\tdir oid %Lu flags %u type %u\n", 40 btrfs_dir_objectid(di), 41 btrfs_dir_flags(di), 42 btrfs_dir_type(di)); 43 printf("\t\tname %.*s\n", 44 namelen, (char *)(di + 1)); 45 46 break; 47 case BTRFS_ROOT_ITEM_KEY: 48 ri = btrfs_item_ptr(l, i, struct btrfs_root_item); 49 printf("\t\troot data blocknr %Lu refs %u\n", 50 btrfs_root_blocknr(ri), btrfs_root_refs(ri)); 51 break; 52 case BTRFS_EXTENT_ITEM_KEY: 53 ei = btrfs_item_ptr(l, i, struct btrfs_extent_item); 54 printf("\t\textent data refs %u owner %Lu\n", 55 btrfs_extent_refs(ei), btrfs_extent_owner(ei)); 56 break; 57 case BTRFS_STRING_ITEM_KEY: 58 printf("\t\titem data %.*s\n", btrfs_item_size(item), 59 btrfs_leaf_data(l) + btrfs_item_offset(item)); 60 break; 61 }; 62 fflush(stdout); 63 } 64 } 65 void btrfs_print_tree(struct btrfs_root *root, struct btrfs_buffer *t) 66 { 67 int i; 68 u32 nr; 69 struct btrfs_node *c; 70 71 if (!t) 72 return; 73 c = &t->node; 74 nr = btrfs_header_nritems(&c->header); 75 if (btrfs_is_leaf(c)) { 76 btrfs_print_leaf(root, (struct btrfs_leaf *)c); 77 return; 78 } 79 printf("node %Lu level %d total ptrs %d free spc %u\n", t->blocknr, 80 btrfs_header_level(&c->header), nr, 81 (u32)BTRFS_NODEPTRS_PER_BLOCK(root) - nr); 82 fflush(stdout); 83 for (i = 0; i < nr; i++) { 84 printf("\tkey %d (%Lu %u %Lu) block %Lu\n", 85 i, 86 c->ptrs[i].key.objectid, 87 c->ptrs[i].key.flags, 88 c->ptrs[i].key.offset, 89 btrfs_node_blockptr(c, i)); 90 fflush(stdout); 91 } 92 for (i = 0; i < nr; i++) { 93 struct btrfs_buffer *next_buf = read_tree_block(root, 94 btrfs_node_blockptr(c, i)); 95 struct btrfs_node *next = &next_buf->node; 96 if (btrfs_is_leaf(next) && 97 btrfs_header_level(&c->header) != 1) 98 BUG(); 99 if (btrfs_header_level(&next->header) != 100 btrfs_header_level(&c->header) - 1) 101 BUG(); 102 btrfs_print_tree(root, next_buf); 103 btrfs_block_release(root, next_buf); 104 } 105 } 106 107