|
@@ -4227,6 +4227,24 @@ out:
|
|
|
space_info->chunk_alloc = 0;
|
|
|
spin_unlock(&space_info->lock);
|
|
|
mutex_unlock(&fs_info->chunk_mutex);
|
|
|
+ /*
|
|
|
+ * When we allocate a new chunk we reserve space in the chunk block
|
|
|
+ * reserve to make sure we can COW nodes/leafs in the chunk tree or
|
|
|
+ * add new nodes/leafs to it if we end up needing to do it when
|
|
|
+ * inserting the chunk item and updating device items as part of the
|
|
|
+ * second phase of chunk allocation, performed by
|
|
|
+ * btrfs_finish_chunk_alloc(). So make sure we don't accumulate a
|
|
|
+ * large number of new block groups to create in our transaction
|
|
|
+ * handle's new_bgs list to avoid exhausting the chunk block reserve
|
|
|
+ * in extreme cases - like having a single transaction create many new
|
|
|
+ * block groups when starting to write out the free space caches of all
|
|
|
+ * the block groups that were made dirty during the lifetime of the
|
|
|
+ * transaction.
|
|
|
+ */
|
|
|
+ if (trans->chunk_bytes_reserved >= (2 * 1024 * 1024ull)) {
|
|
|
+ btrfs_create_pending_block_groups(trans, trans->root);
|
|
|
+ btrfs_trans_release_chunk_metadata(trans);
|
|
|
+ }
|
|
|
return ret;
|
|
|
}
|
|
|
|