- switch (type) {
- case BTRFS_INODE_ITEM_KEY:
- printf("INODE_ITEM");
- break;
- case BTRFS_INODE_REF_KEY:
- printf("INODE_REF");
- break;
- case BTRFS_DIR_ITEM_KEY:
- printf("DIR_ITEM");
- break;
- case BTRFS_DIR_INDEX_KEY:
- printf("DIR_INDEX");
- break;
- case BTRFS_DIR_LOG_ITEM_KEY:
- printf("DIR_LOG_ITEM");
- break;
- case BTRFS_DIR_LOG_INDEX_KEY:
- printf("DIR_LOG_INDEX");
- break;
- case BTRFS_XATTR_ITEM_KEY:
- printf("XATTR_ITEM");
- break;
- case BTRFS_ORPHAN_ITEM_KEY:
- printf("ORPHAN_ITEM");
- break;
- case BTRFS_ROOT_ITEM_KEY:
- printf("ROOT_ITEM");
- break;
- case BTRFS_ROOT_REF_KEY:
- printf("ROOT_REF");
- break;
- case BTRFS_ROOT_BACKREF_KEY:
- printf("ROOT_BACKREF");
- break;
- case BTRFS_EXTENT_ITEM_KEY:
- printf("EXTENT_ITEM");
- break;
- 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");
- break;
- case BTRFS_EXTENT_CSUM_KEY:
- printf("EXTENT_CSUM");
- break;
- case BTRFS_EXTENT_DATA_KEY:
- printf("EXTENT_DATA");
- break;
- case BTRFS_BLOCK_GROUP_ITEM_KEY:
- printf("BLOCK_GROUP_ITEM");
- break;
- case BTRFS_CHUNK_ITEM_KEY:
- printf("CHUNK_ITEM");
- break;
- case BTRFS_DEV_ITEM_KEY:
- printf("DEV_ITEM");
- break;
- case BTRFS_DEV_EXTENT_KEY:
- printf("DEV_EXTENT");
- break;
- case BTRFS_STRING_ITEM_KEY:
- printf("STRING_ITEM");
- break;
- default:
- printf("UNKNOWN");
+ int i;
+
+ for (i = 0; i < BTRFS_UUID_SIZE; i++)
+ if (uuid[i])
+ return 0;
+ return 1;
+}
+
+/*
+ * Caller must ensure sizeof(*ret) >= 7 "RDONLY"
+ */
+static void root_flags_to_str(u64 flags, char *ret)
+{
+ if (flags & BTRFS_ROOT_SUBVOL_RDONLY)
+ strcat(ret, "RDONLY");
+ else
+ strcat(ret, "none");
+}
+
+static void print_timespec(struct extent_buffer *eb,
+ struct btrfs_timespec *timespec, const char *prefix,
+ const char *suffix)
+{
+ struct tm tm;
+ u64 tmp_u64;
+ u32 tmp_u32;
+ time_t tmp_time;
+ char timestamp[256];
+
+ tmp_u64 = btrfs_timespec_sec(eb, timespec);
+ tmp_u32 = btrfs_timespec_nsec(eb, timespec);
+ tmp_time = tmp_u64;
+ localtime_r(&tmp_time, &tm);
+ strftime(timestamp, sizeof(timestamp),
+ "%Y-%m-%d %H:%M:%S", &tm);
+ printf("%s%llu.%u (%s)%s", prefix, (unsigned long long)tmp_u64, tmp_u32,
+ timestamp, suffix);
+}
+
+static void print_root_item(struct extent_buffer *leaf, int slot)
+{
+ struct btrfs_root_item *ri;
+ struct btrfs_root_item root_item;
+ int len;
+ char uuid_str[BTRFS_UUID_UNPARSED_SIZE];
+ char flags_str[32] = {0};
+ struct btrfs_key drop_key;
+
+ ri = btrfs_item_ptr(leaf, slot, struct btrfs_root_item);
+ len = btrfs_item_size_nr(leaf, slot);
+
+ memset(&root_item, 0, sizeof(root_item));
+ read_extent_buffer(leaf, &root_item, (unsigned long)ri, len);
+ root_flags_to_str(btrfs_root_flags(&root_item), flags_str);
+
+ printf("\t\tgeneration %llu root_dirid %llu bytenr %llu level %hhu refs %u\n",
+ (unsigned long long)btrfs_root_generation(&root_item),
+ (unsigned long long)btrfs_root_dirid(&root_item),
+ (unsigned long long)btrfs_root_bytenr(&root_item),
+ btrfs_root_level(&root_item),
+ btrfs_root_refs(&root_item));
+ printf("\t\tlastsnap %llu byte_limit %llu bytes_used %llu flags 0x%llx(%s)\n",
+ (unsigned long long)btrfs_root_last_snapshot(&root_item),
+ (unsigned long long)btrfs_root_limit(&root_item),
+ (unsigned long long)btrfs_root_used(&root_item),
+ (unsigned long long)btrfs_root_flags(&root_item),
+ flags_str);
+
+ if (root_item.generation == root_item.generation_v2) {
+ uuid_unparse(root_item.uuid, uuid_str);
+ printf("\t\tuuid %s\n", uuid_str);
+ if (!empty_uuid(root_item.parent_uuid)) {
+ uuid_unparse(root_item.parent_uuid, uuid_str);
+ printf("\t\tparent_uuid %s\n", uuid_str);
+ }
+ if (!empty_uuid(root_item.received_uuid)) {
+ uuid_unparse(root_item.received_uuid, uuid_str);
+ printf("\t\treceived_uuid %s\n", uuid_str);
+ }
+ if (root_item.ctransid) {
+ printf("\t\tctransid %llu otransid %llu stransid %llu rtransid %llu\n",
+ btrfs_root_ctransid(&root_item),
+ btrfs_root_otransid(&root_item),
+ btrfs_root_stransid(&root_item),
+ btrfs_root_rtransid(&root_item));
+ }
+ if (btrfs_timespec_sec(leaf, btrfs_root_ctime(ri)))
+ print_timespec(leaf, btrfs_root_ctime(ri),
+ "\t\tctime ", "\n");
+ if (btrfs_timespec_sec(leaf, btrfs_root_otime(ri)))
+ print_timespec(leaf, btrfs_root_otime(ri),
+ "\t\totime ", "\n");
+ if (btrfs_timespec_sec(leaf, btrfs_root_stime(ri)))
+ print_timespec(leaf, btrfs_root_stime(ri),
+ "\t\tstime ", "\n");
+ if (btrfs_timespec_sec(leaf, btrfs_root_rtime(ri)))
+ print_timespec(leaf, btrfs_root_rtime(ri),
+ "\t\trtime ", "\n");
+ }
+
+ btrfs_disk_key_to_cpu(&drop_key, &root_item.drop_progress);
+ printf("\t\tdrop ");
+ btrfs_print_key(&root_item.drop_progress);
+ printf(" level %hhu\n", root_item.drop_level);
+}
+
+static void print_free_space_header(struct extent_buffer *leaf, int slot)
+{
+ struct btrfs_free_space_header *header;
+ struct btrfs_disk_key location;
+
+ header = btrfs_item_ptr(leaf, slot, struct btrfs_free_space_header);
+ btrfs_free_space_key(leaf, header, &location);
+ printf("\t\tlocation ");
+ btrfs_print_key(&location);
+ printf("\n");
+ printf("\t\tcache generation %llu entries %llu bitmaps %llu\n",
+ (unsigned long long)btrfs_free_space_generation(leaf, header),
+ (unsigned long long)btrfs_free_space_entries(leaf, header),
+ (unsigned long long)btrfs_free_space_bitmaps(leaf, header));
+}
+
+void print_key_type(FILE *stream, u64 objectid, u8 type)
+{
+ static const char* key_to_str[256] = {
+ [BTRFS_INODE_ITEM_KEY] = "INODE_ITEM",
+ [BTRFS_INODE_REF_KEY] = "INODE_REF",
+ [BTRFS_INODE_EXTREF_KEY] = "INODE_EXTREF",
+ [BTRFS_DIR_ITEM_KEY] = "DIR_ITEM",
+ [BTRFS_DIR_INDEX_KEY] = "DIR_INDEX",
+ [BTRFS_DIR_LOG_ITEM_KEY] = "DIR_LOG_ITEM",
+ [BTRFS_DIR_LOG_INDEX_KEY] = "DIR_LOG_INDEX",
+ [BTRFS_XATTR_ITEM_KEY] = "XATTR_ITEM",
+ [BTRFS_ORPHAN_ITEM_KEY] = "ORPHAN_ITEM",
+ [BTRFS_ROOT_ITEM_KEY] = "ROOT_ITEM",
+ [BTRFS_ROOT_REF_KEY] = "ROOT_REF",
+ [BTRFS_ROOT_BACKREF_KEY] = "ROOT_BACKREF",
+ [BTRFS_EXTENT_ITEM_KEY] = "EXTENT_ITEM",
+ [BTRFS_METADATA_ITEM_KEY] = "METADATA_ITEM",
+ [BTRFS_TREE_BLOCK_REF_KEY] = "TREE_BLOCK_REF",
+ [BTRFS_SHARED_BLOCK_REF_KEY] = "SHARED_BLOCK_REF",
+ [BTRFS_EXTENT_DATA_REF_KEY] = "EXTENT_DATA_REF",
+ [BTRFS_SHARED_DATA_REF_KEY] = "SHARED_DATA_REF",
+ [BTRFS_EXTENT_REF_V0_KEY] = "EXTENT_REF_V0",
+ [BTRFS_CSUM_ITEM_KEY] = "CSUM_ITEM",
+ [BTRFS_EXTENT_CSUM_KEY] = "EXTENT_CSUM",
+ [BTRFS_EXTENT_DATA_KEY] = "EXTENT_DATA",
+ [BTRFS_BLOCK_GROUP_ITEM_KEY] = "BLOCK_GROUP_ITEM",
+ [BTRFS_FREE_SPACE_INFO_KEY] = "FREE_SPACE_INFO",
+ [BTRFS_FREE_SPACE_EXTENT_KEY] = "FREE_SPACE_EXTENT",
+ [BTRFS_FREE_SPACE_BITMAP_KEY] = "FREE_SPACE_BITMAP",
+ [BTRFS_CHUNK_ITEM_KEY] = "CHUNK_ITEM",
+ [BTRFS_DEV_ITEM_KEY] = "DEV_ITEM",
+ [BTRFS_DEV_EXTENT_KEY] = "DEV_EXTENT",
+ [BTRFS_TEMPORARY_ITEM_KEY] = "TEMPORARY_ITEM",
+ [BTRFS_DEV_REPLACE_KEY] = "DEV_REPLACE",
+ [BTRFS_STRING_ITEM_KEY] = "STRING_ITEM",
+ [BTRFS_QGROUP_STATUS_KEY] = "QGROUP_STATUS",
+ [BTRFS_QGROUP_RELATION_KEY] = "QGROUP_RELATION",
+ [BTRFS_QGROUP_INFO_KEY] = "QGROUP_INFO",
+ [BTRFS_QGROUP_LIMIT_KEY] = "QGROUP_LIMIT",
+ [BTRFS_PERSISTENT_ITEM_KEY] = "PERSISTENT_ITEM",
+ [BTRFS_UUID_KEY_SUBVOL] = "UUID_KEY_SUBVOL",
+ [BTRFS_UUID_KEY_RECEIVED_SUBVOL] = "UUID_KEY_RECEIVED_SUBVOL",