Commit e3cbf945 authored by Joe Thornber's avatar Joe Thornber Committed by Alasdair G Kergon

dm persistent data: fix nested btree deletion

When deleting nested btrees, the code forgets to delete the innermost
btree.  The thin-metadata code serendipitously compensates for this by
claiming there is one extra layer in the tree.

This patch corrects both problems.
Signed-off-by: default avatarJoe Thornber <ejt@redhat.com>
Signed-off-by: default avatarAlasdair G Kergon <agk@redhat.com>
parent 563af186
...@@ -408,7 +408,7 @@ static void __setup_btree_details(struct dm_pool_metadata *pmd) ...@@ -408,7 +408,7 @@ static void __setup_btree_details(struct dm_pool_metadata *pmd)
pmd->tl_info.tm = pmd->tm; pmd->tl_info.tm = pmd->tm;
pmd->tl_info.levels = 1; pmd->tl_info.levels = 1;
pmd->tl_info.value_type.context = &pmd->info; pmd->tl_info.value_type.context = &pmd->bl_info;
pmd->tl_info.value_type.size = sizeof(__le64); pmd->tl_info.value_type.size = sizeof(__le64);
pmd->tl_info.value_type.inc = subtree_inc; pmd->tl_info.value_type.inc = subtree_inc;
pmd->tl_info.value_type.dec = subtree_dec; pmd->tl_info.value_type.dec = subtree_dec;
......
...@@ -230,6 +230,11 @@ static void pop_frame(struct del_stack *s) ...@@ -230,6 +230,11 @@ static void pop_frame(struct del_stack *s)
dm_tm_unlock(s->tm, f->b); dm_tm_unlock(s->tm, f->b);
} }
static bool is_internal_level(struct dm_btree_info *info, struct frame *f)
{
return f->level < (info->levels - 1);
}
int dm_btree_del(struct dm_btree_info *info, dm_block_t root) int dm_btree_del(struct dm_btree_info *info, dm_block_t root)
{ {
int r; int r;
...@@ -241,7 +246,7 @@ int dm_btree_del(struct dm_btree_info *info, dm_block_t root) ...@@ -241,7 +246,7 @@ int dm_btree_del(struct dm_btree_info *info, dm_block_t root)
s->tm = info->tm; s->tm = info->tm;
s->top = -1; s->top = -1;
r = push_frame(s, root, 1); r = push_frame(s, root, 0);
if (r) if (r)
goto out; goto out;
...@@ -267,7 +272,7 @@ int dm_btree_del(struct dm_btree_info *info, dm_block_t root) ...@@ -267,7 +272,7 @@ int dm_btree_del(struct dm_btree_info *info, dm_block_t root)
if (r) if (r)
goto out; goto out;
} else if (f->level != (info->levels - 1)) { } else if (is_internal_level(info, f)) {
b = value64(f->n, f->current_child); b = value64(f->n, f->current_child);
f->current_child++; f->current_child++;
r = push_frame(s, b, f->level + 1); r = push_frame(s, b, f->level + 1);
......
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