From d2af024349737b78524405e2c36303ab695cc257 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Tue, 19 Mar 2024 12:07:16 +0100 Subject: [PATCH] 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 --- repos/gems/src/lib/tresor/free_tree.cc | 13 ++++++++++--- .../gems/src/lib/tresor/include/tresor/free_tree.h | 2 +- .../tresor/include/tresor/virtual_block_device.h | 2 +- repos/gems/src/lib/tresor/virtual_block_device.cc | 13 ++++++++++--- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/repos/gems/src/lib/tresor/free_tree.cc b/repos/gems/src/lib/tresor/free_tree.cc index 472a232d26..a22e2f939c 100644 --- a/repos/gems/src/lib/tresor/free_tree.cc +++ b/repos/gems/src/lib/tresor/free_tree.cc @@ -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) diff --git a/repos/gems/src/lib/tresor/include/tresor/free_tree.h b/repos/gems/src/lib/tresor/include/tresor/free_tree.h index 3f9a434c36..ec710b5a66 100644 --- a/repos/gems/src/lib/tresor/include/tresor/free_tree.h +++ b/repos/gems/src/lib/tresor/include/tresor/free_tree.h @@ -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 &); diff --git a/repos/gems/src/lib/tresor/include/tresor/virtual_block_device.h b/repos/gems/src/lib/tresor/include/tresor/virtual_block_device.h index b5df8f4655..ea3d15f46e 100644 --- a/repos/gems/src/lib/tresor/include/tresor/virtual_block_device.h +++ b/repos/gems/src/lib/tresor/include/tresor/virtual_block_device.h @@ -282,7 +282,7 @@ class Tresor::Virtual_block_device::Extend_tree : Noncopyable Generatable_request _write_block { }; Generatable_request _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); diff --git a/repos/gems/src/lib/tresor/virtual_block_device.cc b/repos/gems/src/lib/tresor/virtual_block_device.cc index 2ffdb87a1b..85ff8ecab3 100644 --- a/repos/gems/src/lib/tresor/virtual_block_device.cc +++ b/repos/gems/src/lib/tresor/virtual_block_device.cc @@ -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; }