int make_btrfs(int fd, const char *device, const char *label, u64 blocks[7], u64 num_bytes, u32 nodesize, u32 leafsize, u32 sectorsize, u32 stripesize, u64 features) { struct btrfs_super_block super; struct extent_buffer *buf; struct btrfs_root_item root_item; struct btrfs_disk_key disk_key; struct btrfs_extent_item *extent_item; struct btrfs_inode_item *inode_item; struct btrfs_chunk *chunk; struct btrfs_dev_item *dev_item; struct btrfs_dev_extent *dev_extent; u8 chunk_tree_uuid[BTRFS_UUID_SIZE]; u8 *ptr; int i; int ret; u32 itemoff; u32 nritems = 0; u64 first_free; u64 ref_root; u32 array_size; u32 item_size; int skinny_metadata = !!(features & BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA); first_free = BTRFS_SUPER_INFO_OFFSET + sectorsize * 2 - 1; first_free &= ~((u64)sectorsize - 1); memset(&super, 0, sizeof(super)); num_bytes = (num_bytes / sectorsize) * sectorsize; uuid_generate(super.fsid); uuid_generate(super.dev_item.uuid); uuid_generate(chunk_tree_uuid); btrfs_set_super_bytenr(&super, blocks[0]); btrfs_set_super_num_devices(&super, 1); btrfs_set_super_magic(&super, BTRFS_MAGIC); btrfs_set_super_generation(&super, 1); btrfs_set_super_root(&super, blocks[1]); btrfs_set_super_chunk_root(&super, blocks[3]); btrfs_set_super_total_bytes(&super, num_bytes); btrfs_set_super_bytes_used(&super, 6 * leafsize); btrfs_set_super_sectorsize(&super, sectorsize); btrfs_set_super_leafsize(&super, leafsize); btrfs_set_super_nodesize(&super, nodesize); btrfs_set_super_stripesize(&super, stripesize); btrfs_set_super_csum_type(&super, BTRFS_CSUM_TYPE_CRC32); btrfs_set_super_chunk_root_generation(&super, 1); btrfs_set_super_cache_generation(&super, -1); btrfs_set_super_incompat_flags(&super, features); if (label) strncpy(super.label, label, BTRFS_LABEL_SIZE - 1); buf = malloc(sizeof(*buf) + max(sectorsize, leafsize)); /* create the tree of root objects */ memset(buf->data, 0, leafsize); buf->len = leafsize; btrfs_set_header_bytenr(buf, blocks[1]); btrfs_set_header_nritems(buf, 4); btrfs_set_header_generation(buf, 1); btrfs_set_header_backref_rev(buf, BTRFS_MIXED_BACKREF_REV); btrfs_set_header_owner(buf, BTRFS_ROOT_TREE_OBJECTID); write_extent_buffer(buf, super.fsid, btrfs_header_fsid(), BTRFS_FSID_SIZE); write_extent_buffer(buf, chunk_tree_uuid, (unsigned long) btrfs_header_chunk_tree_uuid(buf), BTRFS_UUID_SIZE); /* create the items for the root tree */ memset(&root_item, 0, sizeof(root_item)); inode_item = &root_item.inode; btrfs_set_stack_inode_generation(inode_item, 1); btrfs_set_stack_inode_size(inode_item, 3); btrfs_set_stack_inode_nlink(inode_item, 1); btrfs_set_stack_inode_nbytes(inode_item, leafsize); btrfs_set_stack_inode_mode(inode_item, S_IFDIR | 0755); btrfs_set_root_refs(&root_item, 1); btrfs_set_root_used(&root_item, leafsize); btrfs_set_root_generation(&root_item, 1); memset(&disk_key, 0, sizeof(disk_key)); btrfs_set_disk_key_type(&disk_key, BTRFS_ROOT_ITEM_KEY); btrfs_set_disk_key_offset(&disk_key, 0); nritems = 0; itemoff = __BTRFS_LEAF_DATA_SIZE(leafsize) - sizeof(root_item); btrfs_set_root_bytenr(&root_item, blocks[2]); btrfs_set_disk_key_objectid(&disk_key, BTRFS_EXTENT_TREE_OBJECTID); btrfs_set_item_key(buf, &disk_key, nritems); btrfs_set_item_offset(buf, btrfs_item_nr(nritems), itemoff); btrfs_set_item_size(buf, btrfs_item_nr(nritems), sizeof(root_item)); write_extent_buffer(buf, &root_item, btrfs_item_ptr_offset(buf, nritems), sizeof(root_item)); nritems++; itemoff = itemoff - sizeof(root_item); btrfs_set_root_bytenr(&root_item, blocks[4]); btrfs_set_disk_key_objectid(&disk_key, BTRFS_DEV_TREE_OBJECTID); btrfs_set_item_key(buf, &disk_key, nritems); btrfs_set_item_offset(buf, btrfs_item_nr(nritems), itemoff); btrfs_set_item_size(buf, btrfs_item_nr(nritems), sizeof(root_item)); write_extent_buffer(buf, &root_item, btrfs_item_ptr_offset(buf, nritems), sizeof(root_item)); nritems++; itemoff = itemoff - sizeof(root_item); btrfs_set_root_bytenr(&root_item, blocks[5]); btrfs_set_disk_key_objectid(&disk_key, BTRFS_FS_TREE_OBJECTID); btrfs_set_item_key(buf, &disk_key, nritems); btrfs_set_item_offset(buf, btrfs_item_nr(nritems), itemoff); btrfs_set_item_size(buf, btrfs_item_nr(nritems), sizeof(root_item)); write_extent_buffer(buf, &root_item, btrfs_item_ptr_offset(buf, nritems), sizeof(root_item)); nritems++; itemoff = itemoff - sizeof(root_item); btrfs_set_root_bytenr(&root_item, blocks[6]); btrfs_set_disk_key_objectid(&disk_key, BTRFS_CSUM_TREE_OBJECTID); btrfs_set_item_key(buf, &disk_key, nritems); btrfs_set_item_offset(buf, btrfs_item_nr(nritems), itemoff); btrfs_set_item_size(buf, btrfs_item_nr(nritems), sizeof(root_item)); write_extent_buffer(buf, &root_item, btrfs_item_ptr_offset(buf, nritems), sizeof(root_item)); nritems++; csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0); ret = pwrite(fd, buf->data, leafsize, blocks[1]); if (ret != leafsize) { ret = (ret < 0 ? -errno : -EIO); goto out; } /* create the items for the extent tree */ memset(buf->data+sizeof(struct btrfs_header), 0, leafsize-sizeof(struct btrfs_header)); nritems = 0; itemoff = __BTRFS_LEAF_DATA_SIZE(leafsize); for (i = 1; i < 7; i++) { item_size = sizeof(struct btrfs_extent_item); if (!skinny_metadata) item_size += sizeof(struct btrfs_tree_block_info); BUG_ON(blocks[i] < first_free); BUG_ON(blocks[i] < blocks[i - 1]); /* create extent item */ itemoff -= item_size; btrfs_set_disk_key_objectid(&disk_key, blocks[i]); if (skinny_metadata) { btrfs_set_disk_key_type(&disk_key, BTRFS_METADATA_ITEM_KEY); btrfs_set_disk_key_offset(&disk_key, 0); } else { btrfs_set_disk_key_type(&disk_key, BTRFS_EXTENT_ITEM_KEY); btrfs_set_disk_key_offset(&disk_key, leafsize); } btrfs_set_item_key(buf, &disk_key, nritems); btrfs_set_item_offset(buf, btrfs_item_nr(nritems), itemoff); btrfs_set_item_size(buf, btrfs_item_nr(nritems), item_size); extent_item = btrfs_item_ptr(buf, nritems, struct btrfs_extent_item); btrfs_set_extent_refs(buf, extent_item, 1); btrfs_set_extent_generation(buf, extent_item, 1); btrfs_set_extent_flags(buf, extent_item, BTRFS_EXTENT_FLAG_TREE_BLOCK); nritems++; /* create extent ref */ ref_root = reference_root_table[i]; btrfs_set_disk_key_objectid(&disk_key, blocks[i]); btrfs_set_disk_key_offset(&disk_key, ref_root); btrfs_set_disk_key_type(&disk_key, BTRFS_TREE_BLOCK_REF_KEY); btrfs_set_item_key(buf, &disk_key, nritems); btrfs_set_item_offset(buf, btrfs_item_nr(nritems), itemoff); btrfs_set_item_size(buf, btrfs_item_nr(nritems), 0); nritems++; } btrfs_set_header_bytenr(buf, blocks[2]); btrfs_set_header_owner(buf, BTRFS_EXTENT_TREE_OBJECTID); btrfs_set_header_nritems(buf, nritems); csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0); ret = pwrite(fd, buf->data, leafsize, blocks[2]); if (ret != leafsize) { ret = (ret < 0 ? -errno : -EIO); goto out; } /* create the chunk tree */ memset(buf->data+sizeof(struct btrfs_header), 0, leafsize-sizeof(struct btrfs_header)); nritems = 0; item_size = sizeof(*dev_item); itemoff = __BTRFS_LEAF_DATA_SIZE(leafsize) - item_size; /* first device 1 (there is no device 0) */ btrfs_set_disk_key_objectid(&disk_key, BTRFS_DEV_ITEMS_OBJECTID); btrfs_set_disk_key_offset(&disk_key, 1); btrfs_set_disk_key_type(&disk_key, BTRFS_DEV_ITEM_KEY); btrfs_set_item_key(buf, &disk_key, nritems); btrfs_set_item_offset(buf, btrfs_item_nr(nritems), itemoff); btrfs_set_item_size(buf, btrfs_item_nr(nritems), item_size); dev_item = btrfs_item_ptr(buf, nritems, struct btrfs_dev_item); btrfs_set_device_id(buf, dev_item, 1); btrfs_set_device_generation(buf, dev_item, 0); btrfs_set_device_total_bytes(buf, dev_item, num_bytes); btrfs_set_device_bytes_used(buf, dev_item, BTRFS_MKFS_SYSTEM_GROUP_SIZE); btrfs_set_device_io_align(buf, dev_item, sectorsize); btrfs_set_device_io_width(buf, dev_item, sectorsize); btrfs_set_device_sector_size(buf, dev_item, sectorsize); btrfs_set_device_type(buf, dev_item, 0); write_extent_buffer(buf, super.dev_item.uuid, (unsigned long)btrfs_device_uuid(dev_item), BTRFS_UUID_SIZE); write_extent_buffer(buf, super.fsid, (unsigned long)btrfs_device_fsid(dev_item), BTRFS_UUID_SIZE); read_extent_buffer(buf, &super.dev_item, (unsigned long)dev_item, sizeof(*dev_item)); nritems++; item_size = btrfs_chunk_item_size(1); itemoff = itemoff - item_size; /* then we have chunk 0 */ btrfs_set_disk_key_objectid(&disk_key, BTRFS_FIRST_CHUNK_TREE_OBJECTID); btrfs_set_disk_key_offset(&disk_key, 0); btrfs_set_disk_key_type(&disk_key, BTRFS_CHUNK_ITEM_KEY); btrfs_set_item_key(buf, &disk_key, nritems); btrfs_set_item_offset(buf, btrfs_item_nr(nritems), itemoff); btrfs_set_item_size(buf, btrfs_item_nr(nritems), item_size); chunk = btrfs_item_ptr(buf, nritems, struct btrfs_chunk); btrfs_set_chunk_length(buf, chunk, BTRFS_MKFS_SYSTEM_GROUP_SIZE); btrfs_set_chunk_owner(buf, chunk, BTRFS_EXTENT_TREE_OBJECTID); btrfs_set_chunk_stripe_len(buf, chunk, 64 * 1024); btrfs_set_chunk_type(buf, chunk, BTRFS_BLOCK_GROUP_SYSTEM); btrfs_set_chunk_io_align(buf, chunk, sectorsize); btrfs_set_chunk_io_width(buf, chunk, sectorsize); btrfs_set_chunk_sector_size(buf, chunk, sectorsize); btrfs_set_chunk_num_stripes(buf, chunk, 1); btrfs_set_stripe_devid_nr(buf, chunk, 0, 1); btrfs_set_stripe_offset_nr(buf, chunk, 0, 0); nritems++; write_extent_buffer(buf, super.dev_item.uuid, (unsigned long)btrfs_stripe_dev_uuid(&chunk->stripe), BTRFS_UUID_SIZE); /* copy the key for the chunk to the system array */ ptr = super.sys_chunk_array; array_size = sizeof(disk_key); memcpy(ptr, &disk_key, sizeof(disk_key)); ptr += sizeof(disk_key); /* copy the chunk to the system array */ read_extent_buffer(buf, ptr, (unsigned long)chunk, item_size); array_size += item_size; ptr += item_size; btrfs_set_super_sys_array_size(&super, array_size); btrfs_set_header_bytenr(buf, blocks[3]); btrfs_set_header_owner(buf, BTRFS_CHUNK_TREE_OBJECTID); btrfs_set_header_nritems(buf, nritems); csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0); ret = pwrite(fd, buf->data, leafsize, blocks[3]); if (ret != leafsize) { ret = (ret < 0 ? -errno : -EIO); goto out; } /* create the device tree */ memset(buf->data+sizeof(struct btrfs_header), 0, leafsize-sizeof(struct btrfs_header)); nritems = 0; itemoff = __BTRFS_LEAF_DATA_SIZE(leafsize) - sizeof(struct btrfs_dev_extent); btrfs_set_disk_key_objectid(&disk_key, 1); btrfs_set_disk_key_offset(&disk_key, 0); btrfs_set_disk_key_type(&disk_key, BTRFS_DEV_EXTENT_KEY); btrfs_set_item_key(buf, &disk_key, nritems); btrfs_set_item_offset(buf, btrfs_item_nr(nritems), itemoff); btrfs_set_item_size(buf, btrfs_item_nr(nritems), sizeof(struct btrfs_dev_extent)); dev_extent = btrfs_item_ptr(buf, nritems, struct btrfs_dev_extent); btrfs_set_dev_extent_chunk_tree(buf, dev_extent, BTRFS_CHUNK_TREE_OBJECTID); btrfs_set_dev_extent_chunk_objectid(buf, dev_extent, BTRFS_FIRST_CHUNK_TREE_OBJECTID); btrfs_set_dev_extent_chunk_offset(buf, dev_extent, 0); write_extent_buffer(buf, chunk_tree_uuid, (unsigned long)btrfs_dev_extent_chunk_tree_uuid(dev_extent), BTRFS_UUID_SIZE); btrfs_set_dev_extent_length(buf, dev_extent, BTRFS_MKFS_SYSTEM_GROUP_SIZE); nritems++; btrfs_set_header_bytenr(buf, blocks[4]); btrfs_set_header_owner(buf, BTRFS_DEV_TREE_OBJECTID); btrfs_set_header_nritems(buf, nritems); csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0); ret = pwrite(fd, buf->data, leafsize, blocks[4]); if (ret != leafsize) { ret = (ret < 0 ? -errno : -EIO); goto out; } /* create the FS root */ memset(buf->data+sizeof(struct btrfs_header), 0, leafsize-sizeof(struct btrfs_header)); btrfs_set_header_bytenr(buf, blocks[5]); btrfs_set_header_owner(buf, BTRFS_FS_TREE_OBJECTID); btrfs_set_header_nritems(buf, 0); csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0); ret = pwrite(fd, buf->data, leafsize, blocks[5]); if (ret != leafsize) { ret = (ret < 0 ? -errno : -EIO); goto out; } /* finally create the csum root */ memset(buf->data+sizeof(struct btrfs_header), 0, leafsize-sizeof(struct btrfs_header)); btrfs_set_header_bytenr(buf, blocks[6]); btrfs_set_header_owner(buf, BTRFS_CSUM_TREE_OBJECTID); btrfs_set_header_nritems(buf, 0); csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0); ret = pwrite(fd, buf->data, leafsize, blocks[6]); if (ret != leafsize) { ret = (ret < 0 ? -errno : -EIO); goto out; } /* and write out the super block */ BUG_ON(sizeof(super) > sectorsize); memset(buf->data, 0, sectorsize); memcpy(buf->data, &super, sizeof(super)); buf->len = sectorsize; csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0); ret = pwrite(fd, buf->data, sectorsize, blocks[0]); if (ret != sectorsize) { ret = (ret < 0 ? -errno : -EIO); goto out; } ret = 0; out: free(buf); return ret; }
void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *eb) { struct btrfs_item *item; struct btrfs_disk_key disk_key; u32 i; u32 nr; nr = btrfs_header_nritems(eb); printf("leaf %llu items %d free space %d generation %llu owner %llu\n", (unsigned long long)btrfs_header_bytenr(eb), nr, btrfs_leaf_free_space(root, eb), (unsigned long long)btrfs_header_generation(eb), (unsigned long long)btrfs_header_owner(eb)); print_uuids(eb); fflush(stdout); for (i = 0; i < nr; i++) { u32 item_size; void *ptr; u64 objectid; u32 type; u64 offset; char flags_str[256]; char uuid_str[BTRFS_UUID_UNPARSED_SIZE]; u8 uuid[BTRFS_UUID_SIZE]; item = btrfs_item_nr(i); item_size = btrfs_item_size(eb, item); /* Untyped extraction of slot from btrfs_item_ptr */ ptr = btrfs_item_ptr(eb, i, void*); btrfs_item_key(eb, &disk_key, i); objectid = btrfs_disk_key_objectid(&disk_key); type = btrfs_disk_key_type(&disk_key); offset = btrfs_disk_key_offset(&disk_key); printf("\titem %d ", i); btrfs_print_key(&disk_key); printf(" itemoff %d itemsize %d\n", btrfs_item_offset(eb, item), btrfs_item_size(eb, item)); if (type == 0 && objectid == BTRFS_FREE_SPACE_OBJECTID) print_free_space_header(eb, i); switch (type) { case BTRFS_INODE_ITEM_KEY: print_inode_item(eb, ptr); break; case BTRFS_INODE_REF_KEY: print_inode_ref_item(eb, item_size, ptr); break; case BTRFS_INODE_EXTREF_KEY: print_inode_extref_item(eb, item_size, ptr); break; case BTRFS_DIR_ITEM_KEY: case BTRFS_DIR_INDEX_KEY: case BTRFS_XATTR_ITEM_KEY: print_dir_item(eb, item_size, ptr); break; case BTRFS_DIR_LOG_INDEX_KEY: case BTRFS_DIR_LOG_ITEM_KEY: { struct btrfs_dir_log_item *dlog; dlog = btrfs_item_ptr(eb, i, struct btrfs_dir_log_item); printf("\t\tdir log end %Lu\n", (unsigned long long)btrfs_dir_log_end(eb, dlog)); break; } case BTRFS_ORPHAN_ITEM_KEY: printf("\t\torphan item\n"); break; case BTRFS_ROOT_ITEM_KEY: print_root(eb, i); break; case BTRFS_ROOT_REF_KEY: print_root_ref(eb, i, "ref"); break; case BTRFS_ROOT_BACKREF_KEY: print_root_ref(eb, i, "backref"); break; case BTRFS_EXTENT_ITEM_KEY: print_extent_item(eb, i, 0); break; case BTRFS_METADATA_ITEM_KEY: print_extent_item(eb, i, 1); break; case BTRFS_TREE_BLOCK_REF_KEY: printf("\t\ttree block backref\n"); break; case BTRFS_SHARED_BLOCK_REF_KEY: printf("\t\tshared block backref\n"); break; case BTRFS_EXTENT_DATA_REF_KEY: { struct btrfs_extent_data_ref *dref; dref = btrfs_item_ptr(eb, 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(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: { struct btrfs_shared_data_ref *sref; sref = btrfs_item_ptr(eb, i, struct btrfs_shared_data_ref); printf("\t\tshared data backref count %u\n", btrfs_shared_data_ref_count(eb, sref)); break; } case BTRFS_EXTENT_REF_V0_KEY: #ifdef BTRFS_COMPAT_EXTENT_TREE_V0 print_extent_ref_v0(eb, i); #else BUG(); #endif break; case BTRFS_CSUM_ITEM_KEY: printf("\t\tcsum item\n"); break; case BTRFS_EXTENT_CSUM_KEY: printf("\t\textent csum item\n"); break; case BTRFS_EXTENT_DATA_KEY: print_file_extent_item(eb, item, i, ptr); break; case BTRFS_BLOCK_GROUP_ITEM_KEY: { struct btrfs_block_group_item bg_item; read_extent_buffer(eb, &bg_item, (unsigned long)ptr, sizeof(bg_item)); memset(flags_str, 0, sizeof(flags_str)); bg_flags_to_str(btrfs_block_group_flags(&bg_item), flags_str); printf("\t\tblock group used %llu chunk_objectid %llu flags %s\n", (unsigned long long)btrfs_block_group_used(&bg_item), (unsigned long long)btrfs_block_group_chunk_objectid(&bg_item), flags_str); break; } case BTRFS_FREE_SPACE_INFO_KEY: { struct btrfs_free_space_info *free_info; free_info = btrfs_item_ptr(eb, i, struct btrfs_free_space_info); printf("\t\tfree space info extent count %u flags %u\n", (unsigned)btrfs_free_space_extent_count(eb, free_info), (unsigned)btrfs_free_space_flags(eb, free_info)); break; } case BTRFS_FREE_SPACE_EXTENT_KEY: printf("\t\tfree space extent\n"); break; case BTRFS_FREE_SPACE_BITMAP_KEY: printf("\t\tfree space bitmap\n"); break; case BTRFS_CHUNK_ITEM_KEY: print_chunk(eb, ptr); break; case BTRFS_DEV_ITEM_KEY: print_dev_item(eb, ptr); break; case BTRFS_DEV_EXTENT_KEY: { struct btrfs_dev_extent *dev_extent; dev_extent = btrfs_item_ptr(eb, i, struct btrfs_dev_extent); read_extent_buffer(eb, uuid, (unsigned long)btrfs_dev_extent_chunk_tree_uuid(dev_extent), BTRFS_UUID_SIZE); uuid_unparse(uuid, uuid_str); printf("\t\tdev extent chunk_tree %llu\n" "\t\tchunk_objectid %llu chunk_offset %llu " "length %llu\n" "\t\tchunk_tree_uuid %s\n", (unsigned long long) btrfs_dev_extent_chunk_tree(eb, dev_extent), (unsigned long long) btrfs_dev_extent_chunk_objectid(eb, dev_extent), (unsigned long long) btrfs_dev_extent_chunk_offset(eb, dev_extent), (unsigned long long) btrfs_dev_extent_length(eb, dev_extent), uuid_str); break; } case BTRFS_QGROUP_STATUS_KEY: { struct btrfs_qgroup_status_item *qg_status; qg_status = btrfs_item_ptr(eb, i, struct btrfs_qgroup_status_item); memset(flags_str, 0, sizeof(flags_str)); qgroup_flags_to_str(btrfs_qgroup_status_flags(eb, qg_status), flags_str); printf("\t\tversion %llu generation %llu flags %s " "scan %lld\n", (unsigned long long) btrfs_qgroup_status_version(eb, qg_status), (unsigned long long) btrfs_qgroup_status_generation(eb, qg_status), flags_str, (unsigned long long) btrfs_qgroup_status_rescan(eb, qg_status)); break; } case BTRFS_QGROUP_RELATION_KEY: break; case BTRFS_QGROUP_INFO_KEY: { struct btrfs_qgroup_info_item *qg_info; qg_info = btrfs_item_ptr(eb, i, struct btrfs_qgroup_info_item); printf("\t\tgeneration %llu\n" "\t\treferenced %llu referenced_compressed %llu\n" "\t\texclusive %llu exclusive_compressed %llu\n", (unsigned long long) btrfs_qgroup_info_generation(eb, qg_info), (unsigned long long) btrfs_qgroup_info_referenced(eb, qg_info), (unsigned long long) btrfs_qgroup_info_referenced_compressed(eb, qg_info), (unsigned long long) btrfs_qgroup_info_exclusive(eb, qg_info), (unsigned long long) btrfs_qgroup_info_exclusive_compressed(eb, qg_info)); break; } case BTRFS_QGROUP_LIMIT_KEY: { struct btrfs_qgroup_limit_item *qg_limit; qg_limit = btrfs_item_ptr(eb, i, struct btrfs_qgroup_limit_item); printf("\t\tflags %llx\n" "\t\tmax_referenced %lld max_exclusive %lld\n" "\t\trsv_referenced %lld rsv_exclusive %lld\n", (unsigned long long) btrfs_qgroup_limit_flags(eb, qg_limit), (long long) btrfs_qgroup_limit_max_referenced(eb, qg_limit), (long long) btrfs_qgroup_limit_max_exclusive(eb, qg_limit), (long long) btrfs_qgroup_limit_rsv_referenced(eb, qg_limit), (long long) btrfs_qgroup_limit_rsv_exclusive(eb, qg_limit)); break; } case BTRFS_UUID_KEY_SUBVOL: case BTRFS_UUID_KEY_RECEIVED_SUBVOL: print_uuid_item(eb, btrfs_item_ptr_offset(eb, i), btrfs_item_size_nr(eb, i)); break; case BTRFS_STRING_ITEM_KEY: { const char *str = eb->data + btrfs_item_ptr_offset(eb, i); printf("\t\titem data %.*s\n", item_size, str); break; } case BTRFS_PERSISTENT_ITEM_KEY: printf("\t\tpersistent item objectid "); print_objectid(stdout, objectid, BTRFS_PERSISTENT_ITEM_KEY); printf(" offset %llu\n", (unsigned long long)offset); switch (objectid) { case BTRFS_DEV_STATS_OBJECTID: print_dev_stats(eb, ptr, item_size); break; default: printf("\t\tunknown persistent item objectid %llu\n", objectid); } break; case BTRFS_TEMPORARY_ITEM_KEY: printf("\t\ttemporary item objectid "); print_objectid(stdout, objectid, BTRFS_TEMPORARY_ITEM_KEY); printf(" offset %llu\n", (unsigned long long)offset); switch (objectid) { case BTRFS_BALANCE_OBJECTID: print_balance_item(eb, ptr); break; default: printf("\t\tunknown temporary item objectid %llu\n", objectid); } break; }; fflush(stdout); } }