mirror of
https://github.com/kdave/btrfs-progs
synced 2024-12-22 06:10:06 +00:00
btrfs-progs: extent-tree: Add add_merge_cache_extent function
This add_merge_cache_extent() function will try to merge adjusted cache_extent. This is used for later btrfs-convert ext2 free space cache. Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
466e066837
commit
f735b37466
@ -282,3 +282,60 @@ void free_extent_cache_tree(struct cache_tree *tree)
|
||||
{
|
||||
cache_tree_free_extents(tree, free_extent_cache);
|
||||
}
|
||||
|
||||
int add_merge_cache_extent(struct cache_tree *tree, u64 start, u64 size)
|
||||
{
|
||||
struct cache_extent *cache;
|
||||
struct cache_extent *next = NULL;
|
||||
struct cache_extent *prev = NULL;
|
||||
int next_merged = 0;
|
||||
int prev_merged = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (cache_tree_empty(tree))
|
||||
goto insert;
|
||||
|
||||
cache = search_cache_extent(tree, start);
|
||||
if (!cache) {
|
||||
/*
|
||||
* Either the tree is completely empty, or the no range after
|
||||
* start.
|
||||
* Either way, the last cache_extent should be prev.
|
||||
*/
|
||||
prev = last_cache_extent(tree);
|
||||
} else if (start <= cache->start) {
|
||||
next = cache;
|
||||
prev = prev_cache_extent(cache);
|
||||
} else {
|
||||
prev = cache;
|
||||
next = next_cache_extent(cache);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure the range to be inserted won't cover with existings
|
||||
* Or we will need extra loop to do merge
|
||||
*/
|
||||
BUG_ON(next && start + size > next->start);
|
||||
BUG_ON(prev && prev->start + prev->size > start);
|
||||
|
||||
if (next && start + size == next->start) {
|
||||
next_merged = 1;
|
||||
next->size = next->start + next->size - start;
|
||||
next->start = start;
|
||||
}
|
||||
if (prev && prev->start + prev->size == start) {
|
||||
prev_merged = 1;
|
||||
if (next_merged) {
|
||||
next->size = next->start + next->size - prev->start;
|
||||
next->start = prev->start;
|
||||
remove_cache_extent(tree, prev);
|
||||
free(prev);
|
||||
} else {
|
||||
prev->size = start + size - prev->start;
|
||||
}
|
||||
}
|
||||
insert:
|
||||
if (!prev_merged && !next_merged)
|
||||
ret = add_cache_extent(tree, start, size);
|
||||
return ret;
|
||||
}
|
||||
|
@ -110,4 +110,12 @@ int add_cache_extent2(struct cache_tree *tree,
|
||||
u64 objectid, u64 start, u64 size);
|
||||
int insert_cache_extent2(struct cache_tree *tree, struct cache_extent *pe);
|
||||
|
||||
/*
|
||||
* Insert a cache_extent range [start, start + size).
|
||||
*
|
||||
* This function may merge with existing cache_extent.
|
||||
* NOTE: caller must ensure the inserted range won't cover with any existing
|
||||
* range.
|
||||
*/
|
||||
int add_merge_cache_extent(struct cache_tree *tree, u64 start, u64 size);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user