forked from Mirrors/btrfs-progs
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>master
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);
|
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);
|
u64 objectid, u64 start, u64 size);
|
||||||
int insert_cache_extent2(struct cache_tree *tree, struct cache_extent *pe);
|
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
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue