mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
tresor: fix faults on failed free-tree requests
* fixes two places, where the free tree module used to continue to process a request after actually having determined that the request fails * moves the functionality of checking the hash of a read block and decoding it to a dedicated method in order to improve readability Ref #5077
This commit is contained in:
parent
81b17ba1e4
commit
067a8a35cd
@ -121,6 +121,37 @@ void Free_tree::Allocate_pbas::_start_tree_traversal(bool &progress)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Free_tree::Extend_tree::_check_and_decode_read_blk(bool &progress)
|
||||||
|
{
|
||||||
|
if (_lvl == _attr.in_out_ft.max_lvl) {
|
||||||
|
if (!check_hash(_blk, _attr.in_out_ft.hash)) {
|
||||||
|
_helper.mark_failed(progress, "hash mismatch");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_t1_blks[_lvl].decode_from_blk(_blk);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Type_1_node &node = _t1_blks[_lvl + 1].nodes[tree_node_index(_vba, _lvl + 1, _attr.in_out_ft.degree)];
|
||||||
|
if (_lvl > 1) {
|
||||||
|
if (!check_hash(_blk, node.hash)) {
|
||||||
|
_helper.mark_failed(progress, "hash mismatch");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_t1_blks[_lvl].decode_from_blk(_blk);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (_lvl == 1) {
|
||||||
|
if (!check_hash(_blk, node.hash)) {
|
||||||
|
_helper.mark_failed(progress, "hash mismatch");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_t2_blk.decode_from_blk(_blk);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
ASSERT_NEVER_REACHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Free_tree::Allocate_pbas::execute(Block_io &block_io, Meta_tree &meta_tree)
|
bool Free_tree::Allocate_pbas::execute(Block_io &block_io, Meta_tree &meta_tree)
|
||||||
{
|
{
|
||||||
bool progress = false;
|
bool progress = false;
|
||||||
@ -173,12 +204,12 @@ bool Free_tree::Allocate_pbas::execute(Block_io &block_io, Meta_tree &meta_tree)
|
|||||||
_attr.in_out_ft.t1_node(_t1_blks[_lvl].nodes[_node_idx[_lvl]]);
|
_attr.in_out_ft.t1_node(_t1_blks[_lvl].nodes[_node_idx[_lvl]]);
|
||||||
_helper.mark_succeeded(progress);
|
_helper.mark_succeeded(progress);
|
||||||
} else {
|
} else {
|
||||||
if (_num_pbas < _attr.in_num_required_pbas)
|
if (_num_pbas < _attr.in_num_required_pbas) {
|
||||||
_helper.mark_failed(progress, "not enough free pbas");
|
_helper.mark_failed(progress, "not enough free pbas");
|
||||||
else {
|
break;
|
||||||
_apply_allocation = true;
|
|
||||||
_start_tree_traversal(progress);
|
|
||||||
}
|
}
|
||||||
|
_apply_allocation = true;
|
||||||
|
_start_tree_traversal(progress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -305,21 +336,13 @@ bool Free_tree::Extend_tree::execute(Block_io &block_io, Meta_tree &meta_tree)
|
|||||||
case READ_BLK: progress |= _read_block.execute(block_io); break;
|
case READ_BLK: progress |= _read_block.execute(block_io); break;
|
||||||
case READ_BLK_SUCCEEDED:
|
case READ_BLK_SUCCEEDED:
|
||||||
|
|
||||||
|
if (!_check_and_decode_read_blk(progress))
|
||||||
|
break;
|
||||||
|
|
||||||
if (_lvl > 1) {
|
if (_lvl > 1) {
|
||||||
|
|
||||||
_t1_blks[_lvl].decode_from_blk(_blk);
|
|
||||||
if (_lvl < _attr.in_out_ft.max_lvl) {
|
|
||||||
Tree_node_index node_idx = tree_node_index(_vba, _lvl + 1, _attr.in_out_ft.degree);
|
|
||||||
if (!check_hash(_blk, _t1_blks[_lvl + 1].nodes[node_idx].hash))
|
|
||||||
_helper.mark_failed(progress, "hash mismatch");
|
|
||||||
} else
|
|
||||||
if (!check_hash(_blk, _attr.in_out_ft.hash))
|
|
||||||
_helper.mark_failed(progress, "hash mismatch");
|
|
||||||
|
|
||||||
Tree_node_index node_idx = tree_node_index(_vba, _lvl, _attr.in_out_ft.degree);
|
Tree_node_index node_idx = tree_node_index(_vba, _lvl, _attr.in_out_ft.degree);
|
||||||
Type_1_node &t1_node = _t1_blks[_lvl].nodes[node_idx];
|
Type_1_node &t1_node = _t1_blks[_lvl].nodes[node_idx];
|
||||||
if (t1_node.valid()) {
|
if (t1_node.valid()) {
|
||||||
|
|
||||||
_lvl--;
|
_lvl--;
|
||||||
_old_pbas.pbas [_lvl] = t1_node.pba;
|
_old_pbas.pbas [_lvl] = t1_node.pba;
|
||||||
_old_generations.items[_lvl] = t1_node.gen;
|
_old_generations.items[_lvl] = t1_node.gen;
|
||||||
@ -340,16 +363,12 @@ bool Free_tree::Extend_tree::execute(Block_io &block_io, Meta_tree &meta_tree)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_t2_blk.decode_from_blk(_blk);
|
Tree_node_index node_idx = tree_node_index(_vba, _lvl, _attr.in_out_ft.degree);
|
||||||
Tree_node_index t1_node_idx = tree_node_index(_vba, _lvl + 1, _attr.in_out_ft.degree);
|
if (_t2_blk.nodes[node_idx].valid()) {
|
||||||
if (!check_hash(_blk, _t1_blks[_lvl + 1].nodes[t1_node_idx].hash))
|
|
||||||
_helper.mark_failed(progress, "hash mismatch");
|
|
||||||
|
|
||||||
Tree_node_index t2_node_idx = tree_node_index(_vba, _lvl, _attr.in_out_ft.degree);
|
|
||||||
if (_t2_blk.nodes[t2_node_idx].valid())
|
|
||||||
_helper.mark_failed(progress, "t2 node valid");
|
_helper.mark_failed(progress, "t2 node valid");
|
||||||
|
break;
|
||||||
_add_new_branch_at(_lvl, t2_node_idx);
|
}
|
||||||
|
_add_new_branch_at(_lvl, node_idx);
|
||||||
_alloc_lvl = _lvl;
|
_alloc_lvl = _lvl;
|
||||||
if (VERBOSE_FT_EXTENSION)
|
if (VERBOSE_FT_EXTENSION)
|
||||||
log(" alloc lvl ", _alloc_lvl);
|
log(" alloc lvl ", _alloc_lvl);
|
||||||
|
@ -152,6 +152,8 @@ class Tresor::Free_tree::Extend_tree : Noncopyable
|
|||||||
Generatable_request<Helper, State, Block_io::Write> _write_block { };
|
Generatable_request<Helper, State, Block_io::Write> _write_block { };
|
||||||
Generatable_request<Helper, State, Meta_tree::Allocate_pba> _allocate_pba { };
|
Generatable_request<Helper, State, Meta_tree::Allocate_pba> _allocate_pba { };
|
||||||
|
|
||||||
|
bool _check_and_decode_read_blk(bool &);
|
||||||
|
|
||||||
void _add_new_branch_at(Tree_level_index, Tree_node_index);
|
void _add_new_branch_at(Tree_level_index, Tree_node_index);
|
||||||
|
|
||||||
bool _add_new_root_lvl();
|
bool _add_new_root_lvl();
|
||||||
|
Loading…
Reference in New Issue
Block a user