mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 06:31:49 +00:00
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: Joe Thornber <ejt@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
This commit is contained in:
parent
563af186df
commit
e3cbf94513
@ -408,7 +408,7 @@ static void __setup_btree_details(struct dm_pool_metadata *pmd)
|
||||
|
||||
pmd->tl_info.tm = pmd->tm;
|
||||
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.inc = subtree_inc;
|
||||
pmd->tl_info.value_type.dec = subtree_dec;
|
||||
|
@ -230,6 +230,11 @@ static void pop_frame(struct del_stack *s)
|
||||
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 r;
|
||||
@ -241,7 +246,7 @@ int dm_btree_del(struct dm_btree_info *info, dm_block_t root)
|
||||
s->tm = info->tm;
|
||||
s->top = -1;
|
||||
|
||||
r = push_frame(s, root, 1);
|
||||
r = push_frame(s, root, 0);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
@ -267,7 +272,7 @@ int dm_btree_del(struct dm_btree_info *info, dm_block_t root)
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
} else if (f->level != (info->levels - 1)) {
|
||||
} else if (is_internal_level(info, f)) {
|
||||
b = value64(f->n, f->current_child);
|
||||
f->current_child++;
|
||||
r = push_frame(s, b, f->level + 1);
|
||||
|
Loading…
Reference in New Issue
Block a user