Commit 6346c939 authored by Josef Bacik's avatar Josef Bacik Committed by Chris Mason

Btrfs: fix data allocation hint start

Sometimes our start allocation hint when we cow a file can be either
EXTENT_HOLE or some other such place holder, which is not optimal.  So if we
find that our em->block_start is one of these special values, check to see
where the first block of the inode is stored, and use that as a hint.  If that
block is also a special value, just fallback on a hint of 0 and let the
allocator figure out a good place to put the data.
Signed-off-by: default avatarJosef Bacik <josef@redhat.com>
Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent 444528b3
...@@ -743,9 +743,23 @@ static noinline int cow_file_range(struct inode *inode, ...@@ -743,9 +743,23 @@ static noinline int cow_file_range(struct inode *inode,
em = search_extent_mapping(&BTRFS_I(inode)->extent_tree, em = search_extent_mapping(&BTRFS_I(inode)->extent_tree,
start, num_bytes); start, num_bytes);
if (em) { if (em) {
/*
* if block start isn't an actual block number then find the
* first block in this inode and use that as a hint. If that
* block is also bogus then just don't worry about it.
*/
if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
free_extent_map(em);
em = search_extent_mapping(em_tree, 0, 0);
if (em && em->block_start < EXTENT_MAP_LAST_BYTE)
alloc_hint = em->block_start;
if (em)
free_extent_map(em);
} else {
alloc_hint = em->block_start; alloc_hint = em->block_start;
free_extent_map(em); free_extent_map(em);
} }
}
read_unlock(&BTRFS_I(inode)->extent_tree.lock); read_unlock(&BTRFS_I(inode)->extent_tree.lock);
btrfs_drop_extent_cache(inode, start, start + num_bytes - 1, 0); btrfs_drop_extent_cache(inode, start, start + num_bytes - 1, 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment