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: Josef Bacik <josef@redhat.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
parent
444528b3e6
commit
6346c93988
|
@ -743,8 +743,22 @@ static noinline int cow_file_range(struct inode *inode,
|
|||
em = search_extent_mapping(&BTRFS_I(inode)->extent_tree,
|
||||
start, num_bytes);
|
||||
if (em) {
|
||||
alloc_hint = em->block_start;
|
||||
free_extent_map(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;
|
||||
free_extent_map(em);
|
||||
}
|
||||
}
|
||||
read_unlock(&BTRFS_I(inode)->extent_tree.lock);
|
||||
btrfs_drop_extent_cache(inode, start, start + num_bytes - 1, 0);
|
||||
|
|
Loading…
Reference in New Issue