Btrfs: clean up code for merging extent maps
unpin_extent_cache() and add_extent_mapping() shares the same code that merges extent maps. Signed-off-by: Li Zefan <lizf@cn.fujitsu.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
parent
ed64f06652
commit
4d2c8f62f1
|
@ -183,22 +183,10 @@ static int mergable_maps(struct extent_map *prev, struct extent_map *next)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len)
|
static void try_merge_map(struct extent_map_tree *tree, struct extent_map *em)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
|
||||||
struct extent_map *merge = NULL;
|
struct extent_map *merge = NULL;
|
||||||
struct rb_node *rb;
|
struct rb_node *rb;
|
||||||
struct extent_map *em;
|
|
||||||
|
|
||||||
write_lock(&tree->lock);
|
|
||||||
em = lookup_extent_mapping(tree, start, len);
|
|
||||||
|
|
||||||
WARN_ON(!em || em->start != start);
|
|
||||||
|
|
||||||
if (!em)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
clear_bit(EXTENT_FLAG_PINNED, &em->flags);
|
|
||||||
|
|
||||||
if (em->start != 0) {
|
if (em->start != 0) {
|
||||||
rb = rb_prev(&em->rb_node);
|
rb = rb_prev(&em->rb_node);
|
||||||
|
@ -225,6 +213,24 @@ int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len)
|
||||||
merge->in_tree = 0;
|
merge->in_tree = 0;
|
||||||
free_extent_map(merge);
|
free_extent_map(merge);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
struct extent_map *em;
|
||||||
|
|
||||||
|
write_lock(&tree->lock);
|
||||||
|
em = lookup_extent_mapping(tree, start, len);
|
||||||
|
|
||||||
|
WARN_ON(!em || em->start != start);
|
||||||
|
|
||||||
|
if (!em)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
clear_bit(EXTENT_FLAG_PINNED, &em->flags);
|
||||||
|
|
||||||
|
try_merge_map(tree, em);
|
||||||
|
|
||||||
free_extent_map(em);
|
free_extent_map(em);
|
||||||
out:
|
out:
|
||||||
|
@ -247,7 +253,6 @@ int add_extent_mapping(struct extent_map_tree *tree,
|
||||||
struct extent_map *em)
|
struct extent_map *em)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct extent_map *merge = NULL;
|
|
||||||
struct rb_node *rb;
|
struct rb_node *rb;
|
||||||
struct extent_map *exist;
|
struct extent_map *exist;
|
||||||
|
|
||||||
|
@ -263,30 +268,8 @@ int add_extent_mapping(struct extent_map_tree *tree,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
atomic_inc(&em->refs);
|
atomic_inc(&em->refs);
|
||||||
if (em->start != 0) {
|
|
||||||
rb = rb_prev(&em->rb_node);
|
try_merge_map(tree, em);
|
||||||
if (rb)
|
|
||||||
merge = rb_entry(rb, struct extent_map, rb_node);
|
|
||||||
if (rb && mergable_maps(merge, em)) {
|
|
||||||
em->start = merge->start;
|
|
||||||
em->len += merge->len;
|
|
||||||
em->block_len += merge->block_len;
|
|
||||||
em->block_start = merge->block_start;
|
|
||||||
merge->in_tree = 0;
|
|
||||||
rb_erase(&merge->rb_node, &tree->map);
|
|
||||||
free_extent_map(merge);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rb = rb_next(&em->rb_node);
|
|
||||||
if (rb)
|
|
||||||
merge = rb_entry(rb, struct extent_map, rb_node);
|
|
||||||
if (rb && mergable_maps(em, merge)) {
|
|
||||||
em->len += merge->len;
|
|
||||||
em->block_len += merge->len;
|
|
||||||
rb_erase(&merge->rb_node, &tree->map);
|
|
||||||
merge->in_tree = 0;
|
|
||||||
free_extent_map(merge);
|
|
||||||
}
|
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue