Skip to content

Commit 4617ea3

Browse files
fdmananamasoncl
authored andcommitted
Btrfs: fix necessary chunk tree space calculation when allocating a chunk
When allocating a new chunk or removing one we need to update num_devs device items and insert or remove a chunk item in the chunk tree, so in the worst case the space needed in the chunk space_info is: btrfs_calc_trunc_metadata_size(chunk_root, num_devs) + btrfs_calc_trans_metadata_size(chunk_root, 1) That is, in the worst case we need to cow num_devs paths and cow 1 other path that can result in splitting every node and leaf, and each path consisting of BTRFS_MAX_LEVEL - 1 nodes and 1 leaf. We were requiring some additional chunk_root->nodesize * BTRFS_MAX_LEVEL * num_devs bytes, which were unnecessary since updating the existing device items does not result in splitting the nodes and leaf since after updating them they remain with the same size. Signed-off-by: Filipe Manana <[email protected]> Signed-off-by: Chris Mason <[email protected]>
1 parent 7558c8b commit 4617ea3

File tree

3 files changed

+7
-12
lines changed

3 files changed

+7
-12
lines changed

fs/btrfs/ctree.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3518,8 +3518,7 @@ int btrfs_start_write_no_snapshoting(struct btrfs_root *root);
35183518
void btrfs_end_write_no_snapshoting(struct btrfs_root *root);
35193519
void check_system_chunk(struct btrfs_trans_handle *trans,
35203520
struct btrfs_root *root,
3521-
const u64 type,
3522-
const bool is_allocation);
3521+
const u64 type);
35233522
/* ctree.c */
35243523
int btrfs_bin_search(struct extent_buffer *eb, struct btrfs_key *key,
35253524
int level, int *slot);

fs/btrfs/extent-tree.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4116,8 +4116,7 @@ static u64 get_profile_num_devs(struct btrfs_root *root, u64 type)
41164116
*/
41174117
void check_system_chunk(struct btrfs_trans_handle *trans,
41184118
struct btrfs_root *root,
4119-
u64 type,
4120-
const bool is_allocation)
4119+
u64 type)
41214120
{
41224121
struct btrfs_space_info *info;
41234122
u64 left;
@@ -4141,11 +4140,8 @@ void check_system_chunk(struct btrfs_trans_handle *trans,
41414140
num_devs = get_profile_num_devs(root, type);
41424141

41434142
/* num_devs device items to update and 1 chunk item to add or remove */
4144-
if (is_allocation)
4145-
thresh = btrfs_calc_trans_metadata_size(root, num_devs + 1);
4146-
else
4147-
thresh = btrfs_calc_trans_metadata_size(root, num_devs) +
4148-
btrfs_calc_trunc_metadata_size(root, 1);
4143+
thresh = btrfs_calc_trunc_metadata_size(root, num_devs) +
4144+
btrfs_calc_trans_metadata_size(root, 1);
41494145

41504146
if (left < thresh && btrfs_test_opt(root, ENOSPC_DEBUG)) {
41514147
btrfs_info(root->fs_info, "left=%llu, need=%llu, flags=%llu",
@@ -4258,7 +4254,7 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
42584254
* Check if we have enough space in SYSTEM chunk because we may need
42594255
* to update devices.
42604256
*/
4261-
check_system_chunk(trans, extent_root, flags, true);
4257+
check_system_chunk(trans, extent_root, flags);
42624258

42634259
ret = btrfs_alloc_chunk(trans, extent_root, flags);
42644260
trans->allocating_chunk = false;
@@ -8926,7 +8922,7 @@ int btrfs_set_block_group_ro(struct btrfs_root *root,
89268922
if (cache->flags & BTRFS_BLOCK_GROUP_SYSTEM) {
89278923
alloc_flags = update_block_group_flags(root, cache->flags);
89288924
lock_chunks(root->fs_info->chunk_root);
8929-
check_system_chunk(trans, root, alloc_flags, true);
8925+
check_system_chunk(trans, root, alloc_flags);
89308926
unlock_chunks(root->fs_info->chunk_root);
89318927
}
89328928
mutex_unlock(&root->fs_info->ro_block_group_mutex);

fs/btrfs/volumes.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2626,7 +2626,7 @@ int btrfs_remove_chunk(struct btrfs_trans_handle *trans,
26262626
}
26272627
map = (struct map_lookup *)em->bdev;
26282628
lock_chunks(root->fs_info->chunk_root);
2629-
check_system_chunk(trans, extent_root, map->type, false);
2629+
check_system_chunk(trans, extent_root, map->type);
26302630
unlock_chunks(root->fs_info->chunk_root);
26312631

26322632
for (i = 0; i < map->num_stripes; i++) {

0 commit comments

Comments
 (0)