diff options
Diffstat (limited to 'print-tree.c')
-rw-r--r-- | print-tree.c | 192 |
1 files changed, 104 insertions, 88 deletions
diff --git a/print-tree.c b/print-tree.c index 60cf27cf..6173503a 100644 --- a/print-tree.c +++ b/print-tree.c @@ -23,50 +23,62 @@ #include "ctree.h" #include "disk-io.h" -static int print_dir_item(struct btrfs_item *item, +static int print_dir_item(struct extent_buffer *eb, struct btrfs_item *item, struct btrfs_dir_item *di) { u32 total; u32 cur = 0; u32 len; - total = btrfs_item_size(item); + u32 name_len; + u32 data_len; + char namebuf[BTRFS_NAME_LEN]; + struct btrfs_disk_key location; + + total = btrfs_item_size(eb, item); while(cur < total) { + btrfs_dir_item_key(eb, di, &location); printf("\t\tdir index %llu type %u\n", - (unsigned long long)btrfs_disk_key_objectid(&di->location), - btrfs_dir_type(di)); - printf("\t\tname: %.*s\n", - btrfs_dir_name_len(di),(char *)(di + 1)); - if (btrfs_dir_data_len(di)) - printf("\t\tdata: %.*s\n", btrfs_dir_data_len(di), - (char *)((char *)(di + 1) + btrfs_dir_name_len(di))); - len = sizeof(*di) + btrfs_dir_name_len(di) + btrfs_dir_data_len(di); + (unsigned long long)btrfs_disk_key_objectid(&location), + btrfs_dir_type(eb, di)); + name_len = btrfs_dir_name_len(eb, di); + data_len = btrfs_dir_data_len(eb, di); + len = (name_len <= sizeof(namebuf))? name_len: sizeof(namebuf); + read_extent_buffer(eb, namebuf, (unsigned long)(di + 1), len); + printf("\t\tnamelen %u datalen %u name: %.*s\n", + name_len, data_len, len, namebuf); + len = sizeof(*di) + name_len + data_len; di = (struct btrfs_dir_item *)((char *)di + len); cur += len; } return 0; } -static int print_inode_ref_item(struct btrfs_item *item, +static int print_inode_ref_item(struct extent_buffer *eb, struct btrfs_item *item, struct btrfs_inode_ref *ref) { u32 total; u32 cur = 0; u32 len; - total = btrfs_item_size(item); + u32 name_len; + char namebuf[BTRFS_NAME_LEN]; + total = btrfs_item_size(eb, item); while(cur < total) { - len = btrfs_inode_ref_name_len(ref); - printf("\t\tinode ref name: %.*s\n", len, (char *)(ref + 1)); - len += sizeof(*ref); + name_len = btrfs_inode_ref_name_len(eb, ref); + len = (name_len <= sizeof(namebuf))? name_len: sizeof(namebuf); + read_extent_buffer(eb, namebuf, (unsigned long)(ref + 1), len); + printf("\t\tinode ref namelen %u name: %.*s\n", + name_len, len, namebuf); + len = sizeof(*ref) + name_len; ref = (struct btrfs_inode_ref *)((char *)ref + len); cur += len; } return 0; } -void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l) +void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) { int i; - u32 nr = btrfs_header_nritems(&l->header); + char *str; struct btrfs_item *item; struct btrfs_extent_item *ei; struct btrfs_root_item *ri; @@ -77,163 +89,167 @@ void btrfs_print_leaf(struct btrfs_root *root, struct btrfs_leaf *l) struct btrfs_block_group_item *bi; struct btrfs_extent_ref *ref; struct btrfs_inode_ref *iref; + struct btrfs_disk_key disk_key; + struct btrfs_root_item root_item; + struct btrfs_block_group_item bg_item; + u32 nr = btrfs_header_nritems(l); u32 type; printf("leaf %llu ptrs %d free space %d generation %llu owner %llu\n", - (unsigned long long)btrfs_header_bytenr(&l->header), nr, + (unsigned long long)btrfs_header_bytenr(l), nr, btrfs_leaf_free_space(root, l), - (unsigned long long)btrfs_header_generation(&l->header), - (unsigned long long)btrfs_header_owner(&l->header)); + (unsigned long long)btrfs_header_generation(l), + (unsigned long long)btrfs_header_owner(l)); fflush(stdout); for (i = 0 ; i < nr ; i++) { - item = l->items + i; - type = btrfs_disk_key_type(&item->key); + item = btrfs_item_nr(l, i); + btrfs_item_key(l, &disk_key, i); + type = btrfs_disk_key_type(&disk_key); printf("\titem %d key (%llu %x %llu) itemoff %d itemsize %d\n", i, - (unsigned long long)btrfs_disk_key_objectid(&item->key), - btrfs_disk_key_type(&item->key), - (unsigned long long)btrfs_disk_key_offset(&item->key), - btrfs_item_offset(item), - btrfs_item_size(item)); + (unsigned long long)btrfs_disk_key_objectid(&disk_key), + btrfs_disk_key_type(&disk_key), + (unsigned long long)btrfs_disk_key_offset(&disk_key), + btrfs_item_offset(l, item), + btrfs_item_size(l, item)); switch (type) { case BTRFS_INODE_ITEM_KEY: ii = btrfs_item_ptr(l, i, struct btrfs_inode_item); printf("\t\tinode generation %llu size %llu block group %llu mode %o links %u\n", - (unsigned long long)btrfs_inode_generation(ii), - (unsigned long long)btrfs_inode_size(ii), - (unsigned long long)btrfs_inode_block_group(ii), - btrfs_inode_mode(ii), - btrfs_inode_nlink(ii)); + (unsigned long long)btrfs_inode_generation(l, ii), + (unsigned long long)btrfs_inode_size(l, ii), + (unsigned long long)btrfs_inode_block_group(l,ii), + btrfs_inode_mode(l, ii), + btrfs_inode_nlink(l, ii)); break; case BTRFS_INODE_REF_KEY: iref = btrfs_item_ptr(l, i, struct btrfs_inode_ref); - print_inode_ref_item(l->items + i, iref); + print_inode_ref_item(l, item, iref); break; case BTRFS_DIR_ITEM_KEY: - di = btrfs_item_ptr(l, i, struct btrfs_dir_item); - print_dir_item(l->items + i, di); - break; - case BTRFS_XATTR_ITEM_KEY: case BTRFS_DIR_INDEX_KEY: + case BTRFS_XATTR_ITEM_KEY: di = btrfs_item_ptr(l, i, struct btrfs_dir_item); - print_dir_item(l->items + i, di); + print_dir_item(l, item, di); break; case BTRFS_ROOT_ITEM_KEY: ri = btrfs_item_ptr(l, i, struct btrfs_root_item); + read_extent_buffer(l, &root_item, (unsigned long)ri, sizeof(root_item)); printf("\t\troot data bytenr %llu level %d dirid %llu refs %u\n", - (unsigned long long)btrfs_root_bytenr(ri), - ri->level, - (unsigned long long)btrfs_root_dirid(ri), - btrfs_root_refs(ri)); - if (1 || btrfs_root_refs(ri) == 0) { + (unsigned long long)btrfs_root_bytenr(&root_item), + btrfs_root_level(&root_item), + (unsigned long long)btrfs_root_dirid(&root_item), + btrfs_root_refs(&root_item)); + if (1 || btrfs_root_refs(&root_item) == 0) { struct btrfs_key drop_key; btrfs_disk_key_to_cpu(&drop_key, - &ri->drop_progress); + &root_item.drop_progress); printf("\t\tdrop key %Lu %x %Lu level %d\n", (unsigned long long)drop_key.objectid, drop_key.type, (unsigned long long)drop_key.offset, - ri->drop_level); + root_item.drop_level); } break; case BTRFS_EXTENT_ITEM_KEY: ei = btrfs_item_ptr(l, i, struct btrfs_extent_item); printf("\t\textent data refs %u\n", - btrfs_extent_refs(ei)); + btrfs_extent_refs(l, ei)); break; case BTRFS_EXTENT_REF_KEY: ref = btrfs_item_ptr(l, i, struct btrfs_extent_ref); printf("\t\textent back ref root %llu gen %llu " "owner %llu offset %llu\n", - (unsigned long long)btrfs_ref_root(ref), - (unsigned long long)btrfs_ref_generation(ref), - (unsigned long long)btrfs_ref_objectid(ref), - (unsigned long long)btrfs_ref_offset(ref)); + (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; case BTRFS_CSUM_ITEM_KEY: - ci = btrfs_item_ptr(l, i, - struct btrfs_csum_item); + ci = btrfs_item_ptr(l, i, struct btrfs_csum_item); printf("\t\tcsum item\n"); break; case BTRFS_EXTENT_DATA_KEY: fi = btrfs_item_ptr(l, i, struct btrfs_file_extent_item); - if (btrfs_file_extent_type(fi) == + if (btrfs_file_extent_type(l, fi) == BTRFS_FILE_EXTENT_INLINE) { printf("\t\tinline extent data size %u\n", - btrfs_file_extent_inline_len(l->items + i)); + btrfs_file_extent_inline_len(l, item)); break; } printf("\t\textent data disk byte %llu nr %llu\n", - (unsigned long long)btrfs_file_extent_disk_bytenr(fi), - (unsigned long long)btrfs_file_extent_disk_num_bytes(fi)); + (unsigned long long)btrfs_file_extent_disk_bytenr(l, fi), + (unsigned long long)btrfs_file_extent_disk_num_bytes(l, fi)); printf("\t\textent data offset %llu nr %llu\n", - (unsigned long long)btrfs_file_extent_offset(fi), - (unsigned long long)btrfs_file_extent_num_bytes(fi)); + (unsigned long long)btrfs_file_extent_offset(l, fi), + (unsigned long long)btrfs_file_extent_num_bytes(l, fi)); break; case BTRFS_BLOCK_GROUP_ITEM_KEY: bi = btrfs_item_ptr(l, i, struct btrfs_block_group_item); + read_extent_buffer(l, &bg_item, (unsigned long)bi, + sizeof(bg_item)); printf("\t\tblock group used %llu flags %x\n", - (unsigned long long)btrfs_block_group_used(bi), - bi->flags); + (unsigned long long)btrfs_block_group_used(&bg_item), + bg_item.flags); break; case BTRFS_STRING_ITEM_KEY: - printf("\t\titem data %.*s\n", btrfs_item_size(item), - btrfs_leaf_data(l) + btrfs_item_offset(item)); + /* dirty, but it's simple */ + str = l->data + btrfs_item_ptr_offset(l, i); + printf("\t\titem data %.*s\n", btrfs_item_size(l, item), str); break; }; fflush(stdout); } } -void btrfs_print_tree(struct btrfs_root *root, struct btrfs_buffer *t) +void btrfs_print_tree(struct btrfs_root *root, struct extent_buffer *eb) { int i; u32 nr; - struct btrfs_node *c; u32 size; + struct btrfs_key key; - if (!t) + if (!eb) return; - c = &t->node; - nr = btrfs_header_nritems(&c->header); - if (btrfs_is_leaf(c)) { - btrfs_print_leaf(root, (struct btrfs_leaf *)c); + nr = btrfs_header_nritems(eb); + if (btrfs_is_leaf(eb)) { + btrfs_print_leaf(root, eb); return; } printf("node %llu level %d ptrs %d free %u generation %llu owner %llu\n", - (unsigned long long)t->bytenr, - btrfs_header_level(&c->header), nr, + (unsigned long long)eb->start, + btrfs_header_level(eb), nr, (u32)BTRFS_NODEPTRS_PER_BLOCK(root) - nr, - (unsigned long long)btrfs_header_generation(&c->header), - (unsigned long long)btrfs_header_owner(&c->header)); + (unsigned long long)btrfs_header_generation(eb), + (unsigned long long)btrfs_header_owner(eb)); fflush(stdout); - size = btrfs_level_size(root, btrfs_header_level(&c->header) - 1); + size = btrfs_level_size(root, btrfs_header_level(eb) - 1); for (i = 0; i < nr; i++) { - u64 blocknr = btrfs_node_blockptr(c, i); + u64 blocknr = btrfs_node_blockptr(eb, i); + btrfs_item_key_to_cpu(eb, &key, i); printf("\tkey %d (%llu %x %llu) block %llu (%llu) gen %llu\n", i, - (unsigned long long)c->ptrs[i].key.objectid, - c->ptrs[i].key.type, - (unsigned long long)c->ptrs[i].key.offset, + (unsigned long long)key.objectid, + key.type, + (unsigned long long)key.offset, (unsigned long long)blocknr, (unsigned long long)blocknr / size, - (unsigned long long)btrfs_node_ptr_generation(c, i)); + (unsigned long long)btrfs_node_ptr_generation(eb, i)); fflush(stdout); } for (i = 0; i < nr; i++) { - struct btrfs_buffer *next_buf = read_tree_block(root, - btrfs_node_blockptr(c, i), - size); - struct btrfs_node *next = &next_buf->node; + struct extent_buffer *next = read_tree_block(root, + btrfs_node_blockptr(eb, i), + size); if (btrfs_is_leaf(next) && - btrfs_header_level(&c->header) != 1) + btrfs_header_level(eb) != 1) BUG(); - if (btrfs_header_level(&next->header) != - btrfs_header_level(&c->header) - 1) + if (btrfs_header_level(next) != + btrfs_header_level(eb) - 1) BUG(); - btrfs_print_tree(root, next_buf); - btrfs_block_release(root, next_buf); + btrfs_print_tree(root, next); + free_extent_buffer(next); } } |