diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 171312d51799..07204bf601ed 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -4227,6 +4227,24 @@ out: | |||
4227 | space_info->chunk_alloc = 0; | 4227 | space_info->chunk_alloc = 0; |
4228 | spin_unlock(&space_info->lock); | 4228 | spin_unlock(&space_info->lock); |
4229 | mutex_unlock(&fs_info->chunk_mutex); | 4229 | mutex_unlock(&fs_info->chunk_mutex); |
4230 | /* | ||
4231 | * When we allocate a new chunk we reserve space in the chunk block | ||
4232 | * reserve to make sure we can COW nodes/leafs in the chunk tree or | ||
4233 | * add new nodes/leafs to it if we end up needing to do it when | ||
4234 | * inserting the chunk item and updating device items as part of the | ||
4235 | * second phase of chunk allocation, performed by | ||
4236 | * btrfs_finish_chunk_alloc(). So make sure we don't accumulate a | ||
4237 | * large number of new block groups to create in our transaction | ||
4238 | * handle's new_bgs list to avoid exhausting the chunk block reserve | ||
4239 | * in extreme cases - like having a single transaction create many new | ||
4240 | * block groups when starting to write out the free space caches of all | ||
4241 | * the block groups that were made dirty during the lifetime of the | ||
4242 | * transaction. | ||
4243 | */ | ||
4244 | if (trans->chunk_bytes_reserved >= (2 * 1024 * 1024ull)) { | ||
4245 | btrfs_create_pending_block_groups(trans, trans->root); | ||
4246 | btrfs_trans_release_chunk_metadata(trans); | ||
4247 | } | ||
4230 | return ret; | 4248 | return ret; |
4231 | } | 4249 | } |
4232 | 4250 | ||