tresor: don't halt on extension beyond limits

The request of extending a tree used to halt when it found that
it could not add more levels to the tree because the maximum level index was
reached. Now, the library simply marks the request as failed, leaving it to
the user to handle the error condition.

Ref #5077
This commit is contained in:
Martin Stein 2024-03-19 12:07:16 +01:00 committed by Christian Helmuth
parent b4c4681733
commit d2af024349
4 changed files with 22 additions and 8 deletions

View File

@ -216,9 +216,11 @@ void Free_tree::Extend_tree::_generate_write_blk_req(bool &progress)
}
void Free_tree::Extend_tree::_add_new_root_lvl()
bool Free_tree::Extend_tree::_add_new_root_lvl()
{
ASSERT(_attr.in_out_ft.max_lvl < TREE_MAX_LEVEL);
if (_attr.in_out_ft.max_lvl >= TREE_MAX_LEVEL)
return false;
_attr.in_out_ft.max_lvl++;
_t1_blks[_attr.in_out_ft.max_lvl] = { };
_t1_blks[_attr.in_out_ft.max_lvl].nodes[0] = _attr.in_out_ft.t1_node();
@ -227,6 +229,8 @@ void Free_tree::Extend_tree::_add_new_root_lvl()
if (VERBOSE_FT_EXTENSION)
log(" set root: ", _attr.in_out_ft, "\n set lvl ", _attr.in_out_ft.max_lvl, " node 0: ",
_t1_blks[_attr.in_out_ft.max_lvl].nodes[0]);
return true;
}
@ -287,7 +291,10 @@ bool Free_tree::Extend_tree::execute(Block_io &block_io, Meta_tree &meta_tree)
if (VERBOSE_FT_EXTENSION)
log(" root (", _attr.in_out_ft, "): load to lvl ", _lvl);
} else {
_add_new_root_lvl();
if (!_add_new_root_lvl()) {
_helper.mark_failed(progress, "failed to add new root level to tree");
break;
}
_add_new_branch_at(_attr.in_out_ft.max_lvl, 1);
_generate_write_blk_req(progress);
if (VERBOSE_FT_EXTENSION)

View File

@ -154,7 +154,7 @@ class Tresor::Free_tree::Extend_tree : Noncopyable
void _add_new_branch_at(Tree_level_index, Tree_node_index);
void _add_new_root_lvl();
bool _add_new_root_lvl();
void _generate_write_blk_req(bool &);

View File

@ -282,7 +282,7 @@ class Tresor::Virtual_block_device::Extend_tree : Noncopyable
Generatable_request<Helper, State, Block_io::Write> _write_block { };
Generatable_request<Helper, State, Free_tree::Allocate_pbas> _alloc_pbas { };
void _add_new_root_lvl_to_snap();
bool _add_new_root_lvl_to_snap();
void _add_new_branch_to_snap(Tree_level_index, Tree_node_index);

View File

@ -541,7 +541,10 @@ bool Virtual_block_device::Extend_tree::execute(Block_io &block_io, Free_tree &f
if (VERBOSE_VBD_EXTENSION)
log(" read lvl ", _lvl, " parent snap ", _snap_idx, " ", snap);
} else {
_add_new_root_lvl_to_snap();
if (!_add_new_root_lvl_to_snap()) {
_helper.mark_failed(progress, "failed to add new root level to snapshot");
break;
}
_add_new_branch_to_snap(_attr.in_out_snapshots.items[_snap_idx].max_level, 1);
_set_new_pbas_identical_to_curr_pbas();
_generate_write_blk_req(progress);
@ -634,12 +637,14 @@ bool Virtual_block_device::Extend_tree::execute(Block_io &block_io, Free_tree &f
}
void Virtual_block_device::Extend_tree::_add_new_root_lvl_to_snap()
bool Virtual_block_device::Extend_tree::_add_new_root_lvl_to_snap()
{
Snapshot_index old_idx { _snap_idx };
Snapshot_index &idx { _snap_idx };
Snapshot *snap { _attr.in_out_snapshots.items };
ASSERT(snap[idx].max_level < TREE_MAX_LEVEL);
if (snap[idx].max_level >= TREE_MAX_LEVEL)
return false;
Tree_level_index new_lvl { snap[old_idx].max_level + 1 };
_t1_blks.items[new_lvl] = { };
_t1_blks.items[new_lvl].nodes[0] = { snap[idx].pba, snap[idx].gen, snap[idx].hash };
@ -655,6 +660,8 @@ void Virtual_block_device::Extend_tree::_add_new_root_lvl_to_snap()
if (VERBOSE_VBD_EXTENSION)
log(" update snap ", idx, " ", snap[idx], "\n update lvl ", new_lvl, " child 0 ", _t1_blks.items[new_lvl].nodes[0]);
return true;
}