diff options
Diffstat (limited to 'print-tree.c')
-rw-r--r-- | print-tree.c | 159 |
1 files changed, 144 insertions, 15 deletions
diff --git a/print-tree.c b/print-tree.c index 86033cf3..59f43588 100644 --- a/print-tree.c +++ b/print-tree.c @@ -159,6 +159,107 @@ static void print_file_extent_item(struct extent_buffer *eb, btrfs_file_extent_compression(eb, fi)); } +static void print_extent_item(struct extent_buffer *eb, int slot) +{ + struct btrfs_extent_item *ei; + struct btrfs_extent_inline_ref *iref; + struct btrfs_extent_data_ref *dref; + struct btrfs_shared_data_ref *sref; + struct btrfs_disk_key key; + unsigned long end; + unsigned long ptr; + int type; + u32 item_size = btrfs_item_size_nr(eb, slot); + u64 flags; + u64 offset; + + if (item_size < sizeof(*ei)) { +#ifdef BTRFS_COMPAT_EXTENT_TREE_V0 + struct btrfs_extent_item_v0 *ei0; + BUG_ON(item_size != sizeof(*ei0)); + ei0 = btrfs_item_ptr(eb, slot, struct btrfs_extent_item_v0); + printf("\t\textent refs %u\n", + btrfs_extent_refs_v0(eb, ei0)); + return; +#else + BUG(); +#endif + } + + ei = btrfs_item_ptr(eb, slot, struct btrfs_extent_item); + flags = btrfs_extent_flags(eb, ei); + + printf("\t\textent refs %llu gen %llu flags %llu\n", + (unsigned long long)btrfs_extent_refs(eb, ei), + (unsigned long long)btrfs_extent_generation(eb, ei), + (unsigned long long)flags); + + if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) { + struct btrfs_tree_block_info *info; + info = (struct btrfs_tree_block_info *)(ei + 1); + btrfs_tree_block_key(eb, info, &key); + printf("\t\ttree block key (%llu %x %llu) level %d\n", + (unsigned long long)btrfs_disk_key_objectid(&key), + key.type, + (unsigned long long)btrfs_disk_key_offset(&key), + btrfs_tree_block_level(eb, info)); + iref = (struct btrfs_extent_inline_ref *)(info + 1); + } else { + iref = (struct btrfs_extent_inline_ref *)(ei + 1); + } + + ptr = (unsigned long)iref; + end = (unsigned long)ei + item_size; + while (ptr < end) { + iref = (struct btrfs_extent_inline_ref *)ptr; + type = btrfs_extent_inline_ref_type(eb, iref); + offset = btrfs_extent_inline_ref_offset(eb, iref); + switch (type) { + case BTRFS_TREE_BLOCK_REF_KEY: + printf("\t\ttree block backref root %llu\n", + (unsigned long long)offset); + break; + case BTRFS_SHARED_BLOCK_REF_KEY: + printf("\t\tshared block backref parent %llu\n", + (unsigned long long)offset); + break; + case BTRFS_EXTENT_DATA_REF_KEY: + dref = (struct btrfs_extent_data_ref *)(&iref->offset); + printf("\t\textent data backref root %llu " + "objectid %llu offset %llu count %u\n", + (unsigned long long)btrfs_extent_data_ref_root(eb, dref), + (unsigned long long)btrfs_extent_data_ref_objectid(eb, dref), + (unsigned long long)btrfs_extent_data_ref_offset(eb, dref), + btrfs_extent_data_ref_count(eb, dref)); + break; + case BTRFS_SHARED_DATA_REF_KEY: + sref = (struct btrfs_shared_data_ref *)(iref + 1); + printf("\t\tshared data backref parent %llu count %u\n", + (unsigned long long)offset, + btrfs_shared_data_ref_count(eb, sref)); + break; + default: + BUG(); + } + ptr += btrfs_extent_inline_ref_size(type); + } + WARN_ON(ptr > end); +} + +#ifdef BTRFS_COMPAT_EXTENT_TREE_V0 +static void print_extent_ref_v0(struct extent_buffer *eb, int slot) +{ + struct btrfs_extent_ref_v0 *ref0; + + ref0 = btrfs_item_ptr(eb, slot, struct btrfs_extent_ref_v0); + printf("\t\textent back ref root %llu gen %llu " + "owner %llu num_refs %lu\n", + (unsigned long long)btrfs_ref_root_v0(eb, ref0), + (unsigned long long)btrfs_ref_generation_v0(eb, ref0), + (unsigned long long)btrfs_ref_objectid_v0(eb, ref0), + (unsigned long)btrfs_ref_count_v0(eb, ref0)); +} +#endif static void print_root_ref(struct extent_buffer *leaf, int slot, char *tag) { @@ -214,8 +315,20 @@ static void print_key_type(u8 type) case BTRFS_EXTENT_ITEM_KEY: printf("EXTENT_ITEM"); break; - case BTRFS_EXTENT_REF_KEY: - printf("EXTENT_REF"); + case BTRFS_TREE_BLOCK_REF_KEY: + printf("TREE_BLOCK_REF"); + break; + case BTRFS_SHARED_BLOCK_REF_KEY: + printf("SHARED_BLOCK_REF"); + break; + case BTRFS_EXTENT_DATA_REF_KEY: + printf("EXTENT_DATA_REF"); + break; + case BTRFS_SHARED_DATA_REF_KEY: + printf("SHARED_DATA_REF"); + break; + case BTRFS_EXTENT_REF_V0_KEY: + printf("EXTENT_REF_V0"); break; case BTRFS_CSUM_ITEM_KEY: printf("CSUM_ITEM"); @@ -324,14 +437,14 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) int i; char *str; struct btrfs_item *item; - struct btrfs_extent_item *ei; struct btrfs_root_item *ri; struct btrfs_dir_item *di; struct btrfs_inode_item *ii; struct btrfs_file_extent_item *fi; struct btrfs_csum_item *ci; struct btrfs_block_group_item *bi; - struct btrfs_extent_ref *ref; + struct btrfs_extent_data_ref *dref; + struct btrfs_shared_data_ref *sref; struct btrfs_inode_ref *iref; struct btrfs_dev_extent *dev_extent; struct btrfs_disk_key disk_key; @@ -410,18 +523,34 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) print_root_ref(l, i, "backref"); 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(l, ei)); + print_extent_item(l, i); + break; + case BTRFS_TREE_BLOCK_REF_KEY: + printf("\t\ttree block backref\n"); 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 num_refs %lu\n", - (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)btrfs_ref_num_refs(l, ref)); + case BTRFS_SHARED_BLOCK_REF_KEY: + printf("\t\tshared block backref\n"); + break; + case BTRFS_EXTENT_DATA_REF_KEY: + dref = btrfs_item_ptr(l, i, struct btrfs_extent_data_ref); + printf("\t\textent data backref root %llu " + "objectid %llu offset %llu count %u\n", + (unsigned long long)btrfs_extent_data_ref_root(l, dref), + (unsigned long long)btrfs_extent_data_ref_objectid(l, dref), + (unsigned long long)btrfs_extent_data_ref_offset(l, dref), + btrfs_extent_data_ref_count(l, dref)); + break; + case BTRFS_SHARED_DATA_REF_KEY: + sref = btrfs_item_ptr(l, i, struct btrfs_shared_data_ref); + printf("\t\tshared data backref count %u\n", + btrfs_shared_data_ref_count(l, sref)); + break; + case BTRFS_EXTENT_REF_V0_KEY: +#ifdef BTRFS_COMPAT_EXTENT_TREE_V0 + print_extent_ref_v0(l, i); +#else + BUG(); +#endif break; case BTRFS_CSUM_ITEM_KEY: ci = btrfs_item_ptr(l, i, struct btrfs_csum_item); |