mirror of
https://github.com/kdave/btrfs-progs
synced 2025-01-12 00:39:35 +00:00
btrfs-progs: add basic awareness of the free space tree
To start, let's tell btrfs-progs to read the free space root and how to print the on-disk format of the free space tree. However, we're not adding the FREE_SPACE_TREE read-only compat bit to the set of supported bits because progs doesn't know how to keep the free space tree consistent. Signed-off-by: Omar Sandoval <osandov@fb.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
32c063ccb7
commit
d8c537e71f
@ -376,6 +376,10 @@ again:
|
||||
if (!skip)
|
||||
printf("uuid");
|
||||
break;
|
||||
case BTRFS_FREE_SPACE_TREE_OBJECTID:
|
||||
if (!skip)
|
||||
printf("free space");
|
||||
break;
|
||||
case BTRFS_MULTIPLE_OBJECTIDS:
|
||||
if (!skip) {
|
||||
printf("multiple");
|
||||
|
49
ctree.h
49
ctree.h
@ -76,6 +76,9 @@ struct btrfs_free_space_ctl;
|
||||
/* for storing items that use the BTRFS_UUID_KEY* */
|
||||
#define BTRFS_UUID_TREE_OBJECTID 9ULL
|
||||
|
||||
/* tracks free space in block groups. */
|
||||
#define BTRFS_FREE_SPACE_TREE_OBJECTID 10ULL
|
||||
|
||||
/* for storing balance parameters in the root tree */
|
||||
#define BTRFS_BALANCE_OBJECTID -4ULL
|
||||
|
||||
@ -453,6 +456,8 @@ struct btrfs_super_block {
|
||||
* Compat flags that we support. If any incompat flags are set other than the
|
||||
* ones specified below then we will fail to mount
|
||||
*/
|
||||
#define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE (1ULL << 0)
|
||||
|
||||
#define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF (1ULL << 0)
|
||||
#define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (1ULL << 1)
|
||||
#define BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS (1ULL << 2)
|
||||
@ -476,9 +481,10 @@ struct btrfs_super_block {
|
||||
#define BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA (1ULL << 8)
|
||||
#define BTRFS_FEATURE_INCOMPAT_NO_HOLES (1ULL << 9)
|
||||
|
||||
|
||||
#define BTRFS_FEATURE_COMPAT_SUPP 0ULL
|
||||
|
||||
#define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL
|
||||
|
||||
#define BTRFS_FEATURE_INCOMPAT_SUPP \
|
||||
(BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF | \
|
||||
BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL | \
|
||||
@ -898,6 +904,13 @@ struct btrfs_block_group_item {
|
||||
__le64 flags;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
struct btrfs_free_space_info {
|
||||
__le32 extent_count;
|
||||
__le32 flags;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
#define BTRFS_FREE_SPACE_USING_BITMAPS (1ULL << 0)
|
||||
|
||||
struct btrfs_qgroup_info_item {
|
||||
__le64 generation;
|
||||
__le64 referenced;
|
||||
@ -965,6 +978,7 @@ struct btrfs_fs_info {
|
||||
struct btrfs_root *dev_root;
|
||||
struct btrfs_root *csum_root;
|
||||
struct btrfs_root *quota_root;
|
||||
struct btrfs_root *free_space_root;
|
||||
|
||||
struct rb_root fs_root_tree;
|
||||
|
||||
@ -1157,6 +1171,27 @@ struct btrfs_root {
|
||||
*/
|
||||
#define BTRFS_BLOCK_GROUP_ITEM_KEY 192
|
||||
|
||||
/*
|
||||
* Every block group is represented in the free space tree by a free space info
|
||||
* item, which stores some accounting information. It is keyed on
|
||||
* (block_group_start, FREE_SPACE_INFO, block_group_length).
|
||||
*/
|
||||
#define BTRFS_FREE_SPACE_INFO_KEY 198
|
||||
|
||||
/*
|
||||
* A free space extent tracks an extent of space that is free in a block group.
|
||||
* It is keyed on (start, FREE_SPACE_EXTENT, length).
|
||||
*/
|
||||
#define BTRFS_FREE_SPACE_EXTENT_KEY 199
|
||||
|
||||
/*
|
||||
* When a block group becomes very fragmented, we convert it to use bitmaps
|
||||
* instead of extents. A free space bitmap is keyed on
|
||||
* (start, FREE_SPACE_BITMAP, length); the corresponding item is a bitmap with
|
||||
* (length / sectorsize) bits.
|
||||
*/
|
||||
#define BTRFS_FREE_SPACE_BITMAP_KEY 200
|
||||
|
||||
#define BTRFS_DEV_EXTENT_KEY 204
|
||||
#define BTRFS_DEV_ITEM_KEY 216
|
||||
#define BTRFS_CHUNK_ITEM_KEY 228
|
||||
@ -1394,6 +1429,11 @@ BTRFS_SETGET_FUNCS(disk_block_group_flags,
|
||||
BTRFS_SETGET_STACK_FUNCS(block_group_flags,
|
||||
struct btrfs_block_group_item, flags, 64);
|
||||
|
||||
/* struct btrfs_free_space_info */
|
||||
BTRFS_SETGET_FUNCS(free_space_extent_count, struct btrfs_free_space_info,
|
||||
extent_count, 32);
|
||||
BTRFS_SETGET_FUNCS(free_space_flags, struct btrfs_free_space_info, flags, 32);
|
||||
|
||||
/* struct btrfs_inode_ref */
|
||||
BTRFS_SETGET_FUNCS(inode_ref_name_len, struct btrfs_inode_ref, name_len, 16);
|
||||
BTRFS_SETGET_STACK_FUNCS(stack_inode_ref_name_len, struct btrfs_inode_ref, name_len, 16);
|
||||
@ -2193,6 +2233,13 @@ static inline int btrfs_fs_incompat(struct btrfs_fs_info *fs_info, u64 flag)
|
||||
return !!(btrfs_super_incompat_flags(disk_super) & flag);
|
||||
}
|
||||
|
||||
static inline int btrfs_fs_compat_ro(struct btrfs_fs_info *fs_info, u64 flag)
|
||||
{
|
||||
struct btrfs_super_block *disk_super;
|
||||
disk_super = fs_info->super_copy;
|
||||
return !!(btrfs_super_compat_ro_flags(disk_super) & flag);
|
||||
}
|
||||
|
||||
/* helper function to cast into the data area of the leaf. */
|
||||
#define btrfs_item_ptr(leaf, slot, type) \
|
||||
((type *)(btrfs_leaf_data(leaf) + \
|
||||
|
16
disk-io.c
16
disk-io.c
@ -811,6 +811,7 @@ void btrfs_free_fs_info(struct btrfs_fs_info *fs_info)
|
||||
free(fs_info->dev_root);
|
||||
free(fs_info->csum_root);
|
||||
free(fs_info->quota_root);
|
||||
free(fs_info->free_space_root);
|
||||
free(fs_info->super_copy);
|
||||
free(fs_info->log_root_tree);
|
||||
free(fs_info);
|
||||
@ -830,12 +831,13 @@ struct btrfs_fs_info *btrfs_new_fs_info(int writable, u64 sb_bytenr)
|
||||
fs_info->dev_root = calloc(1, sizeof(struct btrfs_root));
|
||||
fs_info->csum_root = calloc(1, sizeof(struct btrfs_root));
|
||||
fs_info->quota_root = calloc(1, sizeof(struct btrfs_root));
|
||||
fs_info->free_space_root = calloc(1, sizeof(struct btrfs_root));
|
||||
fs_info->super_copy = calloc(1, BTRFS_SUPER_INFO_SIZE);
|
||||
|
||||
if (!fs_info->tree_root || !fs_info->extent_root ||
|
||||
!fs_info->chunk_root || !fs_info->dev_root ||
|
||||
!fs_info->csum_root || !fs_info->quota_root ||
|
||||
!fs_info->super_copy)
|
||||
!fs_info->free_space_root || !fs_info->super_copy)
|
||||
goto free_all;
|
||||
|
||||
extent_io_tree_init(&fs_info->extent_cache);
|
||||
@ -1016,6 +1018,16 @@ int btrfs_setup_all_roots(struct btrfs_fs_info *fs_info, u64 root_tree_bytenr,
|
||||
if (ret == 0)
|
||||
fs_info->quota_enabled = 1;
|
||||
|
||||
if (btrfs_fs_compat_ro(fs_info, BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE)) {
|
||||
ret = find_and_setup_root(root, fs_info, BTRFS_FREE_SPACE_TREE_OBJECTID,
|
||||
fs_info->free_space_root);
|
||||
if (ret) {
|
||||
printk("Couldn't read free space tree\n");
|
||||
return -EIO;
|
||||
}
|
||||
fs_info->free_space_root->track_dirty = 1;
|
||||
}
|
||||
|
||||
ret = find_and_setup_log_root(root, fs_info, sb);
|
||||
if (ret) {
|
||||
printk("Couldn't setup log root tree\n");
|
||||
@ -1041,6 +1053,8 @@ int btrfs_setup_all_roots(struct btrfs_fs_info *fs_info, u64 root_tree_bytenr,
|
||||
|
||||
void btrfs_release_all_roots(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
if (fs_info->free_space_root)
|
||||
free_extent_buffer(fs_info->free_space_root->node);
|
||||
if (fs_info->quota_root)
|
||||
free_extent_buffer(fs_info->quota_root->node);
|
||||
if (fs_info->csum_root)
|
||||
|
25
print-tree.c
25
print-tree.c
@ -619,6 +619,15 @@ static void print_key_type(u64 objectid, u8 type)
|
||||
case BTRFS_BLOCK_GROUP_ITEM_KEY:
|
||||
printf("BLOCK_GROUP_ITEM");
|
||||
break;
|
||||
case BTRFS_FREE_SPACE_INFO_KEY:
|
||||
printf("FREE_SPACE_INFO");
|
||||
break;
|
||||
case BTRFS_FREE_SPACE_EXTENT_KEY:
|
||||
printf("FREE_SPACE_EXTENT");
|
||||
break;
|
||||
case BTRFS_FREE_SPACE_BITMAP_KEY:
|
||||
printf("FREE_SPACE_BITMAP");
|
||||
break;
|
||||
case BTRFS_CHUNK_ITEM_KEY:
|
||||
printf("CHUNK_ITEM");
|
||||
break;
|
||||
@ -737,6 +746,9 @@ static void print_objectid(u64 objectid, u8 type)
|
||||
case BTRFS_UUID_TREE_OBJECTID:
|
||||
printf("UUID_TREE");
|
||||
break;
|
||||
case BTRFS_FREE_SPACE_TREE_OBJECTID:
|
||||
printf("FREE_SPACE_TREE");
|
||||
break;
|
||||
case BTRFS_MULTIPLE_OBJECTIDS:
|
||||
printf("MULTIPLE");
|
||||
break;
|
||||
@ -819,6 +831,7 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
|
||||
struct btrfs_dev_extent *dev_extent;
|
||||
struct btrfs_disk_key disk_key;
|
||||
struct btrfs_block_group_item bg_item;
|
||||
struct btrfs_free_space_info *free_info;
|
||||
struct btrfs_dir_log_item *dlog;
|
||||
struct btrfs_qgroup_info_item *qg_info;
|
||||
struct btrfs_qgroup_limit_item *qg_limit;
|
||||
@ -956,6 +969,18 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
|
||||
(unsigned long long)btrfs_block_group_chunk_objectid(&bg_item),
|
||||
flags_str);
|
||||
break;
|
||||
case BTRFS_FREE_SPACE_INFO_KEY:
|
||||
free_info = btrfs_item_ptr(l, i, struct btrfs_free_space_info);
|
||||
printf("\t\tfree space info extent count %u flags %u\n",
|
||||
(unsigned)btrfs_free_space_extent_count(l, free_info),
|
||||
(unsigned)btrfs_free_space_flags(l, 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(l, btrfs_item_ptr(l, i, struct btrfs_chunk));
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user