diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
| -rw-r--r-- | fs/btrfs/extent-tree.c | 95 |
1 files changed, 53 insertions, 42 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index b457f195636e..98ca149bdbc8 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -105,6 +105,7 @@ void btrfs_put_block_group(struct btrfs_block_group_cache *cache) | |||
| 105 | WARN_ON(cache->pinned > 0); | 105 | WARN_ON(cache->pinned > 0); |
| 106 | WARN_ON(cache->reserved > 0); | 106 | WARN_ON(cache->reserved > 0); |
| 107 | WARN_ON(cache->reserved_pinned > 0); | 107 | WARN_ON(cache->reserved_pinned > 0); |
| 108 | kfree(cache->free_space_ctl); | ||
| 108 | kfree(cache); | 109 | kfree(cache); |
| 109 | } | 110 | } |
| 110 | } | 111 | } |
| @@ -3036,7 +3037,8 @@ int btrfs_check_data_free_space(struct inode *inode, u64 bytes) | |||
| 3036 | /* make sure bytes are sectorsize aligned */ | 3037 | /* make sure bytes are sectorsize aligned */ |
| 3037 | bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); | 3038 | bytes = (bytes + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); |
| 3038 | 3039 | ||
| 3039 | if (root == root->fs_info->tree_root) { | 3040 | if (root == root->fs_info->tree_root || |
| 3041 | BTRFS_I(inode)->location.objectid == BTRFS_FREE_INO_OBJECTID) { | ||
| 3040 | alloc_chunk = 0; | 3042 | alloc_chunk = 0; |
| 3041 | committed = 1; | 3043 | committed = 1; |
| 3042 | } | 3044 | } |
| @@ -3834,12 +3836,6 @@ static void release_global_block_rsv(struct btrfs_fs_info *fs_info) | |||
| 3834 | WARN_ON(fs_info->chunk_block_rsv.reserved > 0); | 3836 | WARN_ON(fs_info->chunk_block_rsv.reserved > 0); |
| 3835 | } | 3837 | } |
| 3836 | 3838 | ||
| 3837 | static u64 calc_trans_metadata_size(struct btrfs_root *root, int num_items) | ||
| 3838 | { | ||
| 3839 | return (root->leafsize + root->nodesize * (BTRFS_MAX_LEVEL - 1)) * | ||
| 3840 | 3 * num_items; | ||
| 3841 | } | ||
| 3842 | |||
| 3843 | int btrfs_trans_reserve_metadata(struct btrfs_trans_handle *trans, | 3839 | int btrfs_trans_reserve_metadata(struct btrfs_trans_handle *trans, |
| 3844 | struct btrfs_root *root, | 3840 | struct btrfs_root *root, |
| 3845 | int num_items) | 3841 | int num_items) |
| @@ -3850,7 +3846,7 @@ int btrfs_trans_reserve_metadata(struct btrfs_trans_handle *trans, | |||
| 3850 | if (num_items == 0 || root->fs_info->chunk_root == root) | 3846 | if (num_items == 0 || root->fs_info->chunk_root == root) |
| 3851 | return 0; | 3847 | return 0; |
| 3852 | 3848 | ||
| 3853 | num_bytes = calc_trans_metadata_size(root, num_items); | 3849 | num_bytes = btrfs_calc_trans_metadata_size(root, num_items); |
| 3854 | ret = btrfs_block_rsv_add(trans, root, &root->fs_info->trans_block_rsv, | 3850 | ret = btrfs_block_rsv_add(trans, root, &root->fs_info->trans_block_rsv, |
| 3855 | num_bytes); | 3851 | num_bytes); |
| 3856 | if (!ret) { | 3852 | if (!ret) { |
| @@ -3889,14 +3885,14 @@ int btrfs_orphan_reserve_metadata(struct btrfs_trans_handle *trans, | |||
| 3889 | * If all of the metadata space is used, we can commit | 3885 | * If all of the metadata space is used, we can commit |
| 3890 | * transaction and use space it freed. | 3886 | * transaction and use space it freed. |
| 3891 | */ | 3887 | */ |
| 3892 | u64 num_bytes = calc_trans_metadata_size(root, 4); | 3888 | u64 num_bytes = btrfs_calc_trans_metadata_size(root, 4); |
| 3893 | return block_rsv_migrate_bytes(src_rsv, dst_rsv, num_bytes); | 3889 | return block_rsv_migrate_bytes(src_rsv, dst_rsv, num_bytes); |
| 3894 | } | 3890 | } |
| 3895 | 3891 | ||
| 3896 | void btrfs_orphan_release_metadata(struct inode *inode) | 3892 | void btrfs_orphan_release_metadata(struct inode *inode) |
| 3897 | { | 3893 | { |
| 3898 | struct btrfs_root *root = BTRFS_I(inode)->root; | 3894 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 3899 | u64 num_bytes = calc_trans_metadata_size(root, 4); | 3895 | u64 num_bytes = btrfs_calc_trans_metadata_size(root, 4); |
| 3900 | btrfs_block_rsv_release(root, root->orphan_block_rsv, num_bytes); | 3896 | btrfs_block_rsv_release(root, root->orphan_block_rsv, num_bytes); |
| 3901 | } | 3897 | } |
| 3902 | 3898 | ||
| @@ -3910,7 +3906,7 @@ int btrfs_snap_reserve_metadata(struct btrfs_trans_handle *trans, | |||
| 3910 | * two for root back/forward refs, two for directory entries | 3906 | * two for root back/forward refs, two for directory entries |
| 3911 | * and one for root of the snapshot. | 3907 | * and one for root of the snapshot. |
| 3912 | */ | 3908 | */ |
| 3913 | u64 num_bytes = calc_trans_metadata_size(root, 5); | 3909 | u64 num_bytes = btrfs_calc_trans_metadata_size(root, 5); |
| 3914 | dst_rsv->space_info = src_rsv->space_info; | 3910 | dst_rsv->space_info = src_rsv->space_info; |
| 3915 | return block_rsv_migrate_bytes(src_rsv, dst_rsv, num_bytes); | 3911 | return block_rsv_migrate_bytes(src_rsv, dst_rsv, num_bytes); |
| 3916 | } | 3912 | } |
| @@ -3939,7 +3935,7 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) | |||
| 3939 | 3935 | ||
| 3940 | if (nr_extents > reserved_extents) { | 3936 | if (nr_extents > reserved_extents) { |
| 3941 | nr_extents -= reserved_extents; | 3937 | nr_extents -= reserved_extents; |
| 3942 | to_reserve = calc_trans_metadata_size(root, nr_extents); | 3938 | to_reserve = btrfs_calc_trans_metadata_size(root, nr_extents); |
| 3943 | } else { | 3939 | } else { |
| 3944 | nr_extents = 0; | 3940 | nr_extents = 0; |
| 3945 | to_reserve = 0; | 3941 | to_reserve = 0; |
| @@ -3993,7 +3989,7 @@ void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes) | |||
| 3993 | 3989 | ||
| 3994 | to_free = calc_csum_metadata_size(inode, num_bytes); | 3990 | to_free = calc_csum_metadata_size(inode, num_bytes); |
| 3995 | if (nr_extents > 0) | 3991 | if (nr_extents > 0) |
| 3996 | to_free += calc_trans_metadata_size(root, nr_extents); | 3992 | to_free += btrfs_calc_trans_metadata_size(root, nr_extents); |
| 3997 | 3993 | ||
| 3998 | btrfs_block_rsv_release(root, &root->fs_info->delalloc_block_rsv, | 3994 | btrfs_block_rsv_release(root, &root->fs_info->delalloc_block_rsv, |
| 3999 | to_free); | 3995 | to_free); |
| @@ -4754,7 +4750,7 @@ wait_block_group_cache_progress(struct btrfs_block_group_cache *cache, | |||
| 4754 | return 0; | 4750 | return 0; |
| 4755 | 4751 | ||
| 4756 | wait_event(caching_ctl->wait, block_group_cache_done(cache) || | 4752 | wait_event(caching_ctl->wait, block_group_cache_done(cache) || |
| 4757 | (cache->free_space >= num_bytes)); | 4753 | (cache->free_space_ctl->free_space >= num_bytes)); |
| 4758 | 4754 | ||
| 4759 | put_caching_control(caching_ctl); | 4755 | put_caching_control(caching_ctl); |
| 4760 | return 0; | 4756 | return 0; |
| @@ -6908,10 +6904,16 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
| 6908 | ret = -ENOMEM; | 6904 | ret = -ENOMEM; |
| 6909 | goto error; | 6905 | goto error; |
| 6910 | } | 6906 | } |
| 6907 | cache->free_space_ctl = kzalloc(sizeof(*cache->free_space_ctl), | ||
| 6908 | GFP_NOFS); | ||
| 6909 | if (!cache->free_space_ctl) { | ||
| 6910 | kfree(cache); | ||
| 6911 | ret = -ENOMEM; | ||
| 6912 | goto error; | ||
| 6913 | } | ||
| 6911 | 6914 | ||
| 6912 | atomic_set(&cache->count, 1); | 6915 | atomic_set(&cache->count, 1); |
| 6913 | spin_lock_init(&cache->lock); | 6916 | spin_lock_init(&cache->lock); |
| 6914 | spin_lock_init(&cache->tree_lock); | ||
| 6915 | cache->fs_info = info; | 6917 | cache->fs_info = info; |
| 6916 | INIT_LIST_HEAD(&cache->list); | 6918 | INIT_LIST_HEAD(&cache->list); |
| 6917 | INIT_LIST_HEAD(&cache->cluster_list); | 6919 | INIT_LIST_HEAD(&cache->cluster_list); |
| @@ -6919,14 +6921,6 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
| 6919 | if (need_clear) | 6921 | if (need_clear) |
| 6920 | cache->disk_cache_state = BTRFS_DC_CLEAR; | 6922 | cache->disk_cache_state = BTRFS_DC_CLEAR; |
| 6921 | 6923 | ||
| 6922 | /* | ||
| 6923 | * we only want to have 32k of ram per block group for keeping | ||
| 6924 | * track of free space, and if we pass 1/2 of that we want to | ||
| 6925 | * start converting things over to using bitmaps | ||
| 6926 | */ | ||
| 6927 | cache->extents_thresh = ((1024 * 32) / 2) / | ||
| 6928 | sizeof(struct btrfs_free_space); | ||
| 6929 | |||
| 6930 | read_extent_buffer(leaf, &cache->item, | 6924 | read_extent_buffer(leaf, &cache->item, |
| 6931 | btrfs_item_ptr_offset(leaf, path->slots[0]), | 6925 | btrfs_item_ptr_offset(leaf, path->slots[0]), |
| 6932 | sizeof(cache->item)); | 6926 | sizeof(cache->item)); |
| @@ -6937,6 +6931,8 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
| 6937 | cache->flags = btrfs_block_group_flags(&cache->item); | 6931 | cache->flags = btrfs_block_group_flags(&cache->item); |
| 6938 | cache->sectorsize = root->sectorsize; | 6932 | cache->sectorsize = root->sectorsize; |
| 6939 | 6933 | ||
| 6934 | btrfs_init_free_space_ctl(cache); | ||
| 6935 | |||
| 6940 | /* | 6936 | /* |
| 6941 | * We need to exclude the super stripes now so that the space | 6937 | * We need to exclude the super stripes now so that the space |
| 6942 | * info has super bytes accounted for, otherwise we'll think | 6938 | * info has super bytes accounted for, otherwise we'll think |
| @@ -7023,6 +7019,12 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, | |||
| 7023 | cache = kzalloc(sizeof(*cache), GFP_NOFS); | 7019 | cache = kzalloc(sizeof(*cache), GFP_NOFS); |
| 7024 | if (!cache) | 7020 | if (!cache) |
| 7025 | return -ENOMEM; | 7021 | return -ENOMEM; |
| 7022 | cache->free_space_ctl = kzalloc(sizeof(*cache->free_space_ctl), | ||
| 7023 | GFP_NOFS); | ||
| 7024 | if (!cache->free_space_ctl) { | ||
| 7025 | kfree(cache); | ||
| 7026 | return -ENOMEM; | ||
| 7027 | } | ||
| 7026 | 7028 | ||
| 7027 | cache->key.objectid = chunk_offset; | 7029 | cache->key.objectid = chunk_offset; |
| 7028 | cache->key.offset = size; | 7030 | cache->key.offset = size; |
| @@ -7030,19 +7032,13 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, | |||
| 7030 | cache->sectorsize = root->sectorsize; | 7032 | cache->sectorsize = root->sectorsize; |
| 7031 | cache->fs_info = root->fs_info; | 7033 | cache->fs_info = root->fs_info; |
| 7032 | 7034 | ||
| 7033 | /* | ||
| 7034 | * we only want to have 32k of ram per block group for keeping track | ||
| 7035 | * of free space, and if we pass 1/2 of that we want to start | ||
| 7036 | * converting things over to using bitmaps | ||
| 7037 | */ | ||
| 7038 | cache->extents_thresh = ((1024 * 32) / 2) / | ||
| 7039 | sizeof(struct btrfs_free_space); | ||
| 7040 | atomic_set(&cache->count, 1); | 7035 | atomic_set(&cache->count, 1); |
| 7041 | spin_lock_init(&cache->lock); | 7036 | spin_lock_init(&cache->lock); |
| 7042 | spin_lock_init(&cache->tree_lock); | ||
| 7043 | INIT_LIST_HEAD(&cache->list); | 7037 | INIT_LIST_HEAD(&cache->list); |
| 7044 | INIT_LIST_HEAD(&cache->cluster_list); | 7038 | INIT_LIST_HEAD(&cache->cluster_list); |
| 7045 | 7039 | ||
| 7040 | btrfs_init_free_space_ctl(cache); | ||
| 7041 | |||
| 7046 | btrfs_set_block_group_used(&cache->item, bytes_used); | 7042 | btrfs_set_block_group_used(&cache->item, bytes_used); |
| 7047 | btrfs_set_block_group_chunk_objectid(&cache->item, chunk_objectid); | 7043 | btrfs_set_block_group_chunk_objectid(&cache->item, chunk_objectid); |
| 7048 | cache->flags = type; | 7044 | cache->flags = type; |
| @@ -7209,23 +7205,38 @@ out: | |||
| 7209 | int btrfs_init_space_info(struct btrfs_fs_info *fs_info) | 7205 | int btrfs_init_space_info(struct btrfs_fs_info *fs_info) |
| 7210 | { | 7206 | { |
| 7211 | struct btrfs_space_info *space_info; | 7207 | struct btrfs_space_info *space_info; |
| 7208 | struct btrfs_super_block *disk_super; | ||
| 7209 | u64 features; | ||
| 7210 | u64 flags; | ||
| 7211 | int mixed = 0; | ||
| 7212 | int ret; | 7212 | int ret; |
| 7213 | 7213 | ||
| 7214 | ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_SYSTEM, 0, 0, | 7214 | disk_super = &fs_info->super_copy; |
| 7215 | &space_info); | 7215 | if (!btrfs_super_root(disk_super)) |
| 7216 | if (ret) | 7216 | return 1; |
| 7217 | return ret; | ||
| 7218 | 7217 | ||
| 7219 | ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA, 0, 0, | 7218 | features = btrfs_super_incompat_flags(disk_super); |
| 7220 | &space_info); | 7219 | if (features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS) |
| 7221 | if (ret) | 7220 | mixed = 1; |
| 7222 | return ret; | ||
| 7223 | 7221 | ||
| 7224 | ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_DATA, 0, 0, | 7222 | flags = BTRFS_BLOCK_GROUP_SYSTEM; |
| 7225 | &space_info); | 7223 | ret = update_space_info(fs_info, flags, 0, 0, &space_info); |
| 7226 | if (ret) | 7224 | if (ret) |
| 7227 | return ret; | 7225 | goto out; |
| 7228 | 7226 | ||
| 7227 | if (mixed) { | ||
| 7228 | flags = BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA; | ||
| 7229 | ret = update_space_info(fs_info, flags, 0, 0, &space_info); | ||
| 7230 | } else { | ||
| 7231 | flags = BTRFS_BLOCK_GROUP_METADATA; | ||
| 7232 | ret = update_space_info(fs_info, flags, 0, 0, &space_info); | ||
| 7233 | if (ret) | ||
| 7234 | goto out; | ||
| 7235 | |||
| 7236 | flags = BTRFS_BLOCK_GROUP_DATA; | ||
| 7237 | ret = update_space_info(fs_info, flags, 0, 0, &space_info); | ||
| 7238 | } | ||
| 7239 | out: | ||
| 7229 | return ret; | 7240 | return ret; |
| 7230 | } | 7241 | } |
| 7231 | 7242 | ||
