aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c45
1 files changed, 9 insertions, 36 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 9ef8f99d5a2a..7c644f810816 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -5615,48 +5615,21 @@ void btrfs_block_rsv_release(struct btrfs_root *root,
5615 num_bytes); 5615 num_bytes);
5616} 5616}
5617 5617
5618/*
5619 * helper to calculate size of global block reservation.
5620 * the desired value is sum of space used by extent tree,
5621 * checksum tree and root tree
5622 */
5623static u64 calc_global_metadata_size(struct btrfs_fs_info *fs_info)
5624{
5625 struct btrfs_space_info *sinfo;
5626 u64 num_bytes;
5627 u64 meta_used;
5628 u64 data_used;
5629 int csum_size = btrfs_super_csum_size(fs_info->super_copy);
5630
5631 sinfo = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_DATA);
5632 spin_lock(&sinfo->lock);
5633 data_used = sinfo->bytes_used;
5634 spin_unlock(&sinfo->lock);
5635
5636 sinfo = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA);
5637 spin_lock(&sinfo->lock);
5638 if (sinfo->flags & BTRFS_BLOCK_GROUP_DATA)
5639 data_used = 0;
5640 meta_used = sinfo->bytes_used;
5641 spin_unlock(&sinfo->lock);
5642
5643 num_bytes = (data_used >> fs_info->sb->s_blocksize_bits) *
5644 csum_size * 2;
5645 num_bytes += div_u64(data_used + meta_used, 50);
5646
5647 if (num_bytes * 3 > meta_used)
5648 num_bytes = div_u64(meta_used, 3);
5649
5650 return ALIGN(num_bytes, fs_info->extent_root->nodesize << 10);
5651}
5652
5653static void update_global_block_rsv(struct btrfs_fs_info *fs_info) 5618static void update_global_block_rsv(struct btrfs_fs_info *fs_info)
5654{ 5619{
5655 struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv; 5620 struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv;
5656 struct btrfs_space_info *sinfo = block_rsv->space_info; 5621 struct btrfs_space_info *sinfo = block_rsv->space_info;
5657 u64 num_bytes; 5622 u64 num_bytes;
5658 5623
5659 num_bytes = calc_global_metadata_size(fs_info); 5624 /*
5625 * The global block rsv is based on the size of the extent tree, the
5626 * checksum tree and the root tree. If the fs is empty we want to set
5627 * it to a minimal amount for safety.
5628 */
5629 num_bytes = btrfs_root_used(&fs_info->extent_root->root_item) +
5630 btrfs_root_used(&fs_info->csum_root->root_item) +
5631 btrfs_root_used(&fs_info->tree_root->root_item);
5632 num_bytes = max_t(u64, num_bytes, SZ_16M);
5660 5633
5661 spin_lock(&sinfo->lock); 5634 spin_lock(&sinfo->lock);
5662 spin_lock(&block_rsv->lock); 5635 spin_lock(&block_rsv->lock);