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; }