Skip to content
Browse files

btrfs-progs: Do metadata preallocation as long as we're not modifying…

… extent tree

In github issues, one user reports unexpected ENOSPC error if enabling
datasum druing convert.  After some investigation, it looks like that
during ext2_saved/image creation, we could create large file extent
whose size can be 128M (max data extent size).

In that case, its csum block will be at least 128K. Under certain case
we need to allocate extra metadata chunks to fulfill such space

However we only do metadata prealloc if we're reserving extents for fs
trees.  (we use btrfs_root::ref_cows to determine whether we should do
metadata prealloc, and that member is only set for fs trees).

There is no explaination on why we only do metadata prealloc for file
trees, but at least from my investigation, it could be related to avoid
nested extent tree modication.

At least extent reservation for csum tree shouldn't be a problem with
metadata block group preallocation.

So change the metadata block group preallocation check from
"root->ref_cow" to "root->root_key.objectid !=
BTRFS_EXTENT_TREE_OBJECTID", and add some comment for it.

Issue: #123
Signed-off-by: Qu Wenruo <>
Signed-off-by: David Sterba <>
  • Loading branch information...
adam900710 authored and kdave committed Sep 14, 2018
1 parent a838933 commit 4e8eb31f048f3fe9a68aacb58e4c0714df25b5c4
Showing with 6 additions and 1 deletion.
  1. +6 −1 extent-tree.c
@@ -2506,7 +2506,12 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans,
profile = BTRFS_BLOCK_GROUP_METADATA | alloc_profile;

if (root->ref_cows) {
* Do metadata preallocation if we're not modifying the extent tree.
* Allocating chunk while modifying extent tree could lead to transid
* mismatch, as do_chunk_alloc() could commit transaction.
if (root->root_key.objectid != BTRFS_EXTENT_TREE_OBJECTID) {
if (!(profile & BTRFS_BLOCK_GROUP_METADATA)) {
ret = do_chunk_alloc(trans, info,

0 comments on commit 4e8eb31

Please sign in to comment.
You can’t perform that action at this time.