diff options
author | Josef Bacik <jbacik@fb.com> | 2016-03-25 13:25:47 -0400 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2016-07-07 12:45:53 -0400 |
commit | e40edf2da4fc6ab10c707b0522372b08b38171e6 (patch) | |
tree | 085dfa71d90bfc25cc563439544b84417169c9d1 | |
parent | a99cde438de0c4c0cecc1d1af1a55a75b10bfdef (diff) |
Btrfs: add bytes_readonly to the spaceinfo at once
For some reason we're adding bytes_readonly to the space info after we update
the space info with the block group info. This creates a tiny race where we
could over-reserve space because we haven't yet taken out the bytes_readonly
bit. Since we already know this information at the time we call
update_space_info, just pass it along so it can be updated all at once. Thanks,
Signed-off-by: Josef Bacik <jbacik@fb.com>
Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r-- | fs/btrfs/extent-tree.c | 29 |
1 files changed, 11 insertions, 18 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 82b912a293ab..777d9a5aa83f 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -3913,6 +3913,7 @@ static const char *alloc_name(u64 flags) | |||
3913 | 3913 | ||
3914 | static int update_space_info(struct btrfs_fs_info *info, u64 flags, | 3914 | static int update_space_info(struct btrfs_fs_info *info, u64 flags, |
3915 | u64 total_bytes, u64 bytes_used, | 3915 | u64 total_bytes, u64 bytes_used, |
3916 | u64 bytes_readonly, | ||
3916 | struct btrfs_space_info **space_info) | 3917 | struct btrfs_space_info **space_info) |
3917 | { | 3918 | { |
3918 | struct btrfs_space_info *found; | 3919 | struct btrfs_space_info *found; |
@@ -3933,6 +3934,7 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags, | |||
3933 | found->disk_total += total_bytes * factor; | 3934 | found->disk_total += total_bytes * factor; |
3934 | found->bytes_used += bytes_used; | 3935 | found->bytes_used += bytes_used; |
3935 | found->disk_used += bytes_used * factor; | 3936 | found->disk_used += bytes_used * factor; |
3937 | found->bytes_readonly += bytes_readonly; | ||
3936 | if (total_bytes > 0) | 3938 | if (total_bytes > 0) |
3937 | found->full = 0; | 3939 | found->full = 0; |
3938 | spin_unlock(&found->lock); | 3940 | spin_unlock(&found->lock); |
@@ -3960,7 +3962,7 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags, | |||
3960 | found->disk_used = bytes_used * factor; | 3962 | found->disk_used = bytes_used * factor; |
3961 | found->bytes_pinned = 0; | 3963 | found->bytes_pinned = 0; |
3962 | found->bytes_reserved = 0; | 3964 | found->bytes_reserved = 0; |
3963 | found->bytes_readonly = 0; | 3965 | found->bytes_readonly = bytes_readonly; |
3964 | found->bytes_may_use = 0; | 3966 | found->bytes_may_use = 0; |
3965 | found->full = 0; | 3967 | found->full = 0; |
3966 | found->max_extent_size = 0; | 3968 | found->max_extent_size = 0; |
@@ -4470,7 +4472,7 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, | |||
4470 | space_info = __find_space_info(extent_root->fs_info, flags); | 4472 | space_info = __find_space_info(extent_root->fs_info, flags); |
4471 | if (!space_info) { | 4473 | if (!space_info) { |
4472 | ret = update_space_info(extent_root->fs_info, flags, | 4474 | ret = update_space_info(extent_root->fs_info, flags, |
4473 | 0, 0, &space_info); | 4475 | 0, 0, 0, &space_info); |
4474 | BUG_ON(ret); /* -ENOMEM */ | 4476 | BUG_ON(ret); /* -ENOMEM */ |
4475 | } | 4477 | } |
4476 | BUG_ON(!space_info); /* Logic error */ | 4478 | BUG_ON(!space_info); /* Logic error */ |
@@ -10007,7 +10009,7 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
10007 | 10009 | ||
10008 | ret = update_space_info(info, cache->flags, found_key.offset, | 10010 | ret = update_space_info(info, cache->flags, found_key.offset, |
10009 | btrfs_block_group_used(&cache->item), | 10011 | btrfs_block_group_used(&cache->item), |
10010 | &space_info); | 10012 | cache->bytes_super, &space_info); |
10011 | if (ret) { | 10013 | if (ret) { |
10012 | btrfs_remove_free_space_cache(cache); | 10014 | btrfs_remove_free_space_cache(cache); |
10013 | spin_lock(&info->block_group_cache_lock); | 10015 | spin_lock(&info->block_group_cache_lock); |
@@ -10020,9 +10022,6 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
10020 | } | 10022 | } |
10021 | 10023 | ||
10022 | cache->space_info = space_info; | 10024 | cache->space_info = space_info; |
10023 | spin_lock(&cache->space_info->lock); | ||
10024 | cache->space_info->bytes_readonly += cache->bytes_super; | ||
10025 | spin_unlock(&cache->space_info->lock); | ||
10026 | 10025 | ||
10027 | __link_block_group(space_info, cache); | 10026 | __link_block_group(space_info, cache); |
10028 | 10027 | ||
@@ -10114,7 +10113,6 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, | |||
10114 | int ret; | 10113 | int ret; |
10115 | struct btrfs_root *extent_root; | 10114 | struct btrfs_root *extent_root; |
10116 | struct btrfs_block_group_cache *cache; | 10115 | struct btrfs_block_group_cache *cache; |
10117 | |||
10118 | extent_root = root->fs_info->extent_root; | 10116 | extent_root = root->fs_info->extent_root; |
10119 | 10117 | ||
10120 | btrfs_set_log_full_commit(root->fs_info, trans); | 10118 | btrfs_set_log_full_commit(root->fs_info, trans); |
@@ -10160,7 +10158,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, | |||
10160 | * assigned to our block group, but don't update its counters just yet. | 10158 | * assigned to our block group, but don't update its counters just yet. |
10161 | * We want our bg to be added to the rbtree with its ->space_info set. | 10159 | * We want our bg to be added to the rbtree with its ->space_info set. |
10162 | */ | 10160 | */ |
10163 | ret = update_space_info(root->fs_info, cache->flags, 0, 0, | 10161 | ret = update_space_info(root->fs_info, cache->flags, 0, 0, 0, |
10164 | &cache->space_info); | 10162 | &cache->space_info); |
10165 | if (ret) { | 10163 | if (ret) { |
10166 | btrfs_remove_free_space_cache(cache); | 10164 | btrfs_remove_free_space_cache(cache); |
@@ -10180,7 +10178,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, | |||
10180 | * the rbtree, update the space info's counters. | 10178 | * the rbtree, update the space info's counters. |
10181 | */ | 10179 | */ |
10182 | ret = update_space_info(root->fs_info, cache->flags, size, bytes_used, | 10180 | ret = update_space_info(root->fs_info, cache->flags, size, bytes_used, |
10183 | &cache->space_info); | 10181 | cache->bytes_super, &cache->space_info); |
10184 | if (ret) { | 10182 | if (ret) { |
10185 | btrfs_remove_free_space_cache(cache); | 10183 | btrfs_remove_free_space_cache(cache); |
10186 | spin_lock(&root->fs_info->block_group_cache_lock); | 10184 | spin_lock(&root->fs_info->block_group_cache_lock); |
@@ -10193,16 +10191,11 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, | |||
10193 | } | 10191 | } |
10194 | update_global_block_rsv(root->fs_info); | 10192 | update_global_block_rsv(root->fs_info); |
10195 | 10193 | ||
10196 | spin_lock(&cache->space_info->lock); | ||
10197 | cache->space_info->bytes_readonly += cache->bytes_super; | ||
10198 | spin_unlock(&cache->space_info->lock); | ||
10199 | |||
10200 | __link_block_group(cache->space_info, cache); | 10194 | __link_block_group(cache->space_info, cache); |
10201 | 10195 | ||
10202 | list_add_tail(&cache->bg_list, &trans->new_bgs); | 10196 | list_add_tail(&cache->bg_list, &trans->new_bgs); |
10203 | 10197 | ||
10204 | set_avail_alloc_bits(extent_root->fs_info, type); | 10198 | set_avail_alloc_bits(extent_root->fs_info, type); |
10205 | |||
10206 | return 0; | 10199 | return 0; |
10207 | } | 10200 | } |
10208 | 10201 | ||
@@ -10747,21 +10740,21 @@ int btrfs_init_space_info(struct btrfs_fs_info *fs_info) | |||
10747 | mixed = 1; | 10740 | mixed = 1; |
10748 | 10741 | ||
10749 | flags = BTRFS_BLOCK_GROUP_SYSTEM; | 10742 | flags = BTRFS_BLOCK_GROUP_SYSTEM; |
10750 | ret = update_space_info(fs_info, flags, 0, 0, &space_info); | 10743 | ret = update_space_info(fs_info, flags, 0, 0, 0, &space_info); |
10751 | if (ret) | 10744 | if (ret) |
10752 | goto out; | 10745 | goto out; |
10753 | 10746 | ||
10754 | if (mixed) { | 10747 | if (mixed) { |
10755 | flags = BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA; | 10748 | flags = BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA; |
10756 | ret = update_space_info(fs_info, flags, 0, 0, &space_info); | 10749 | ret = update_space_info(fs_info, flags, 0, 0, 0, &space_info); |
10757 | } else { | 10750 | } else { |
10758 | flags = BTRFS_BLOCK_GROUP_METADATA; | 10751 | flags = BTRFS_BLOCK_GROUP_METADATA; |
10759 | ret = update_space_info(fs_info, flags, 0, 0, &space_info); | 10752 | ret = update_space_info(fs_info, flags, 0, 0, 0, &space_info); |
10760 | if (ret) | 10753 | if (ret) |
10761 | goto out; | 10754 | goto out; |
10762 | 10755 | ||
10763 | flags = BTRFS_BLOCK_GROUP_DATA; | 10756 | flags = BTRFS_BLOCK_GROUP_DATA; |
10764 | ret = update_space_info(fs_info, flags, 0, 0, &space_info); | 10757 | ret = update_space_info(fs_info, flags, 0, 0, 0, &space_info); |
10765 | } | 10758 | } |
10766 | out: | 10759 | out: |
10767 | return ret; | 10760 | return ret; |