tresor: fix and test handling of minimal trees

* add testing of trees with minimal and maximal dimensions to tresor_tester.run
* replace tresor_init-local configuration type with simpler and more conformant
  configuration type in tresor/types.h that does also XML-parsing and
  XML-generation of configurations
* raise min degree to 2 because a degree of 1 is not practical und would
  require additional logic
* fix overflow with num_blocks=0 in Superblock_control::Read|Write_vbas
* fix off-by-one bug regarding the number of levels in Vbd_initializer
* improve sanity checks in Tree_configuration constructors
* document level indices in tresor_init/README
* fix size of some arrays in order to be able to handle the maximum number of
  tree levels

Ref #5077
This commit is contained in:
Martin Stein 2024-03-19 06:36:41 +01:00 committed by Christian Helmuth
parent 067a8a35cd
commit b903ddeea7
27 changed files with 294 additions and 362 deletions

View File

@ -240,24 +240,14 @@ append config {
<initialize-trust-anchor passphrase="foobar"/>
<initialize>
<virtual-block-device
nr_of_levels="3"
nr_of_children="8"
nr_of_leafs="64" />
<free-tree
nr_of_levels="4"
nr_of_children="8"
nr_of_leafs="100" />
<virtual-block-device max_lvl="2" degree="8" num_leaves="64" />
<free-tree max_lvl="3" degree="8" num_leaves="100" />
</initialize>
<check/>
<construct/>
<log string="Step 2: test synchronous write, read"/>
<request op="read" vba="1" num_blocks="1" uninitialized_data="yes"/>
<request op="write" vba="1" num_blocks="1" salt="1234"/>
<request op="read" vba="1" num_blocks="1" salt="1234"/>
@ -388,17 +378,8 @@ append config {
<request op="deinitialize" />
<destruct/>
<initialize>
<virtual-block-device
nr_of_levels="4"
nr_of_children="8"
nr_of_leafs="100" />
<free-tree
nr_of_levels="4"
nr_of_children="8"
nr_of_leafs="512" />
<virtual-block-device max_lvl="3" degree="8" num_leaves="100" />
<free-tree max_lvl="3" degree="8" num_leaves="512" />
</initialize>
<construct/>
@ -589,22 +570,77 @@ append config {
<request op="sync" vba="0" num_blocks="256" />
<check/>
<log string="Step 15: reinitialize Tresor device"/>
<log string="Step 15: check minimum vbd dimensions"/>
<request op="deinitialize"/>
<destruct/>
<initialize>
<virtual-block-device max_lvl="1" degree="2" num_leaves="1"/>
<free-tree max_lvl="1" degree="2" num_leaves="1"/>
</initialize>
<check/>
<construct/>
<request op="read" vba="0" num_blocks="1" uninitialized="yes"/>
<request op="write" vba="0" num_blocks="1" salt="4321"/>
<request op="read" vba="0" num_blocks="1" salt="4321"/>
<log string="Step 16: check minimum free tree dimensions"/>
<request op="deinitialize"/>
<destruct/>
<initialize>
<virtual-block-device max_lvl="1" degree="2" num_leaves="1"/>
<free-tree max_lvl="2" degree="64" num_leaves="4096"/>
</initialize>
<construct/>
<check/>
<request op="write" vba="0" num_blocks="1" salt="1234"/>
<request op="read" vba="0" num_blocks="1" salt="1234"/>
<request op="rekey" sync="yes"/>
<request op="write" vba="0" num_blocks="1" salt="4321"/>
<request op="read" vba="0" num_blocks="1" salt="4321"/>
<request op="create_snapshot" id="13"/>
<request op="write" vba="0" num_blocks="1" salt="1234"/>
<request op="rekey"/>
<request op="write" vba="0" num_blocks="1" salt="9465"/>
<request op="read" vba="0" num_blocks="1" salt="9465"/>
<request op="extend_vbd" num_blocks="61" sync="yes"/>
<request op="write" vba="0" num_blocks="32" sync="yes" salt="4321"/>
<request op="read" vba="0" num_blocks="32" salt="4321"/>
<check/>
<check-snapshots/>
<log string="Step 17: check maximum tree dimensions"/>
<destruct/>
<initialize>
<virtual-block-device max_lvl="5" degree="64" num_leaves="100000"/>
<free-tree max_lvl="5" degree="64" num_leaves="100000"/>
</initialize>
<construct/>
<check/>
<request op="write" vba="0" num_blocks="1" salt="1234"/>
<request op="write" vba="99999" num_blocks="1" salt="5463"/>
<request op="read" vba="0" num_blocks="1" salt="1234"/>
<request op="extend_vbd" num_blocks="200"/>
<request op="write" vba="0" num_blocks="1" salt="4567"/>
<request op="read" vba="99999" num_blocks="1" salt="5463"/>
<request op="read" vba="0" num_blocks="1" salt="4567"/>
<request op="extend_ft" num_blocks="200"/>
<request op="write" vba="100" num_blocks="100" salt="1384"/>
<request op="write" vba="99990" num_blocks="30" salt="5463"/>
<request op="read" vba="100" num_blocks="100" salt="1384"/>
<request op="read" vba="99990" num_blocks="30" salt="5463"/>
<check/>
<check-snapshots/>
<log string="Step 18: reinitialize Tresor device"/>
<request op="deinitialize" />
<destruct/>
<initialize>
<virtual-block-device
nr_of_levels="4"
nr_of_children="64"
nr_of_leafs="25600" />
<free-tree
nr_of_levels="4"
nr_of_children="64"
nr_of_leafs="25600" />
<virtual-block-device max_lvl="3" degree="64" num_leaves="25600" />
<free-tree max_lvl="3" degree="64" num_leaves="25600" />
</initialize>
<construct/>
}
@ -612,7 +648,7 @@ if {[benchmark_blk_count] > 0} {
append config {
<log string="Step 16: do read/write benchmarks"/>
<log string="Step 19: do read/write benchmarks"/>
<start-benchmark label="read initial data in one request"/>
<request op="read" vba="0" num_blocks="} [benchmark_blk_count] {" />
@ -1052,18 +1088,18 @@ if {[benchmark_blk_count] > 0} {
append config {
<log string="Step 16: skip because benchmarks are disabled for this platform"/>
<log string="Step 19: skip because benchmarks are disabled for this platform"/>
}
}
append config {
<log string="Step 17: test check-snapshots command"/>
<log string="Step 20: test check-snapshots command"/>
<request op="create_snapshot" id="13"/>
<request op="write" vba="17737" num_blocks="70" salt="8924"/>
<request op="create_snapshot" id="14"/>
<request op="write" vba="00129" num_blocks="30" salt="9471"/>
<request op="create_snapshot" id="15"/>
<request op="write" vba="17737" num_blocks="70" salt="8924"/>
<request op="create_snapshot" id="16"/>
<request op="write" vba="00129" num_blocks="30" salt="9471"/>
<request op="create_snapshot" id="17"/>
<check-snapshots/>
</commands>

View File

@ -98,8 +98,8 @@ append config {
</dir>
</vfs>
<virtual-block-device nr_of_levels="3" nr_of_children="64" nr_of_leafs="512" />
<free-tree nr_of_levels="3" nr_of_children="64" nr_of_leafs="2048" />
<virtual-block-device max_lvl="2" degree="64" num_leaves="512" />
<free-tree max_lvl="2" degree="64" num_leaves="2048" />
</config>
<route>

View File

@ -136,8 +136,8 @@ append config {
</dir>
</vfs>
<virtual-block-device nr_of_levels="3" nr_of_children="64" nr_of_leafs="512" />
<free-tree nr_of_levels="3" nr_of_children="64" nr_of_leafs="2048" />
<virtual-block-device max_lvl="2" degree="64" num_leaves="512" />
<free-tree max_lvl="2" degree="64" num_leaves="2048" />
</config>
<route>

View File

@ -23,6 +23,9 @@
#include <os/reporter.h>
#include <timer_session/connection.h>
/* tresor includes */
#include <tresor/types.h>
/* local includes */
#include <gui_session_component.h>
#include <report_session_component.h>
@ -86,15 +89,16 @@ class File_vault::Main
{
private:
static constexpr Tree_degree TRESOR_VBD_DEGREE = 64;
static constexpr Tree_level_index TRESOR_VBD_MAX_LVL = 5;
static constexpr Tree_degree TRESOR_FREE_TREE_DEGREE = 64;
static constexpr Tree_level_index TRESOR_FREE_TREE_MAX_LVL = 5;
enum {
MIN_CLIENT_FS_SIZE = 100 * 1024,
STATE_STRING_CAPACITY = 64,
TRESOR_BLOCK_SIZE = 4096,
MAIN_FRAME_WIDTH = 46,
TRESOR_VBD_TREE_NR_OF_LEVELS = 6,
TRESOR_VBD_TREE_NR_OF_CHILDREN = 64,
TRESOR_FREE_TREE_NR_OF_LEVELS = 6,
TRESOR_FREE_TREE_NR_OF_CHILDREN = 64,
TRESOR_NR_OF_SUPERBLOCKS = 8,
};
@ -624,7 +628,7 @@ class File_vault::Main
}
}
static size_t _tresor_tree_nr_of_leaves(size_t payload_size);
static Number_of_blocks _tresor_tree_num_leaves(size_t payload_size);
static size_t _tree_nr_of_blocks(size_t nr_of_lvls,
@ -1973,7 +1977,7 @@ void File_vault::Main::produce_xml(Xml_generator &xml)
_expand_client_fs_contingent.value() };
size_t const effective_bytes {
bytes - (bytes % TRESOR_BLOCK_SIZE) };
bytes - (bytes % Tresor::BLOCK_SIZE) };
if (effective_bytes > 0) {
@ -1989,7 +1993,7 @@ void File_vault::Main::produce_xml(Xml_generator &xml)
gen_info_line(xml, "info_1",
String<128> {
"Must be at least ",
Number_of_bytes { TRESOR_BLOCK_SIZE } }.string());
Number_of_bytes { Tresor::BLOCK_SIZE } }.string());
gen_start_button = false;
}
@ -2357,9 +2361,9 @@ void File_vault::Main::wakeup_local_service()
}
size_t Main::_tresor_tree_nr_of_leaves(size_t payload_size)
Number_of_blocks Main::_tresor_tree_num_leaves(size_t payload_size)
{
size_t nr_of_leaves { payload_size / TRESOR_BLOCK_SIZE };
Number_of_blocks nr_of_leaves { payload_size / TRESOR_BLOCK_SIZE };
if (payload_size % TRESOR_BLOCK_SIZE) {
nr_of_leaves++;
}
@ -2439,31 +2443,25 @@ void File_vault::Main::_generate_sandbox_config(Xml_generator &xml) const
TRESOR_BLOCK_SIZE *
_tresor_nr_of_blocks(
TRESOR_NR_OF_SUPERBLOCKS,
TRESOR_VBD_TREE_NR_OF_LEVELS,
TRESOR_VBD_TREE_NR_OF_CHILDREN,
_tresor_tree_nr_of_leaves(_ui_client_fs_size()),
TRESOR_FREE_TREE_NR_OF_LEVELS,
TRESOR_FREE_TREE_NR_OF_CHILDREN,
_tresor_tree_nr_of_leaves(_ui_journaling_buf_size())));
TRESOR_VBD_MAX_LVL + 1,
TRESOR_VBD_DEGREE,
_tresor_tree_num_leaves(_ui_client_fs_size()),
TRESOR_FREE_TREE_MAX_LVL + 1,
TRESOR_FREE_TREE_DEGREE,
_tresor_tree_num_leaves(_ui_journaling_buf_size())));
break;
case State::SETUP_RUN_TRESOR_INIT:
{
Tree_geometry const vbd_tree_geom {
TRESOR_VBD_TREE_NR_OF_LEVELS,
TRESOR_VBD_TREE_NR_OF_CHILDREN,
_tresor_tree_nr_of_leaves(_ui_client_fs_size()) };
Tree_geometry const free_tree_geom {
TRESOR_VBD_TREE_NR_OF_LEVELS,
TRESOR_VBD_TREE_NR_OF_CHILDREN,
_tresor_tree_nr_of_leaves(_ui_journaling_buf_size()) };
Tresor::Superblock_configuration sb_config {
Tree_configuration { TRESOR_VBD_MAX_LVL, TRESOR_VBD_DEGREE, _tresor_tree_num_leaves(_ui_client_fs_size()) },
Tree_configuration { TRESOR_FREE_TREE_MAX_LVL, TRESOR_FREE_TREE_DEGREE, _tresor_tree_num_leaves(_ui_journaling_buf_size()) }
};
gen_parent_provides_and_report_nodes(xml);
_gen_menu_view_start_node_if_required(xml);
gen_tresor_trust_anchor_vfs_start_node(xml, _tresor_trust_anchor_vfs, _jent_avail);
gen_tresor_init_start_node(xml, _tresor_init, vbd_tree_geom, free_tree_geom);
gen_tresor_init_start_node(xml, _tresor_init, sb_config);
break;
}
case State::SETUP_START_TRESOR_VFS:
@ -2698,12 +2696,12 @@ size_t Main::_tresor_size() const
return
_tresor_nr_of_blocks(
TRESOR_NR_OF_SUPERBLOCKS,
TRESOR_VBD_TREE_NR_OF_LEVELS,
TRESOR_VBD_TREE_NR_OF_CHILDREN,
_tresor_tree_nr_of_leaves(_ui_client_fs_size()),
TRESOR_FREE_TREE_NR_OF_LEVELS,
TRESOR_FREE_TREE_NR_OF_CHILDREN,
_tresor_tree_nr_of_leaves(_ui_journaling_buf_size()))
TRESOR_VBD_MAX_LVL + 1,
TRESOR_VBD_DEGREE,
_tresor_tree_num_leaves(_ui_client_fs_size()),
TRESOR_FREE_TREE_MAX_LVL + 1,
TRESOR_FREE_TREE_DEGREE,
_tresor_tree_num_leaves(_ui_journaling_buf_size()))
* TRESOR_BLOCK_SIZE;
}

View File

@ -667,10 +667,9 @@ namespace File_vault {
});
}
void gen_tresor_init_start_node(Xml_generator &xml,
Child_state const &child,
Tree_geometry const &vbd_geom,
Tree_geometry const &ft_geom)
void gen_tresor_init_start_node(Xml_generator &xml,
Child_state const &child,
Tresor::Superblock_configuration sb_config)
{
child.gen_start_node(xml, [&] () {
@ -700,16 +699,7 @@ namespace File_vault {
});
});
});
xml.node("virtual-block-device", [&] () {
xml.attribute("nr_of_levels", vbd_geom.nr_of_levels());
xml.attribute("nr_of_children", vbd_geom.nr_of_children());
xml.attribute("nr_of_leafs", vbd_geom.nr_of_leaves());
});
xml.node("free-tree", [&] () {
xml.attribute("nr_of_levels", ft_geom.nr_of_levels());
xml.attribute("nr_of_children", ft_geom.nr_of_children());
xml.attribute("nr_of_leafs", ft_geom.nr_of_leaves());
});
sb_config.generate_xml(xml);
});
xml.node("route", [&] () {
route_to_child_service(xml, "tresor_trust_anchor_vfs", "File_system", "trust_anchor");

View File

@ -1,6 +1,7 @@
The tresor_check component check the meta data of a Tresor device. This includes
the tree for the virtual block device, free tree and meta tree. On success,
the component exits with exit value 0, otherwise with exit value -1.
The tresor_check component checks the integrity of the meta and payload data of
a Tresor container. This includes the tree for the virtual block device, the
free tree and the meta tree. On success, the component exits with exit value 0,
otherwise with exit value -1.
Sessions
@ -15,5 +16,5 @@ component apart from the environment sessions:
Examples
~~~~~~~~
An example of how to use the tresor_init component can be found in the test script
'tresor/run/tresor_check.run'.
An example of how to use the tresor_check component can be found in the test
script 'gems/run/tresor_utils.run'.

View File

@ -1,62 +1,68 @@
The tresor_init component creates a fresh Tresor device (virtual block device,
free tree and superblocks) on a back-end block-device according to the
configured parameters. On success, the component exits with exit value 0,
otherwise with exit value -1.
The tresor_init component creates a fresh Tresor container on a back-end
block-device according to the configured parameters. On success, the component
exits with exit value 0, otherwise with exit value -1.
Configuration
~~~~~~~~~~~~~
This is an example configuration of the component which shows the default
value for each attribute except 'config.dst_ip' and 'config.interface':
This is an example configuration of the component:
! <config>
! <virtual-block-device
! nr_of_levels="4"
! nr_of_children="64"
! nr_of_leafs="8192" />
!
! <free-tree
! nr_of_levels="3"
! nr_of_children="64"
! nr_of_leafs="1024" />
! <virtual-block-device max_lvl="2" degree="64" num_leaves="512" />
! <free-tree max_lvl="2" degree="64" num_leaves="2048" />
! </config>
This is a short description of the tags and attributes:
:config.virtual-block-device:
Mandatory. Contains parameters for the tree that represents the virtual
block device.
:config.virtual-block-device.degree:
Contains the configuration for the hash tree that forms the virtual block
device of the Tresor container. The leaves of this tree hold the most
recent state of the encrypted payload data stored in the container.
Therefore, the dimensions of this tree define the storage capacity of the
container.
:config.virtual-block-device.nr_of_levels:
Mandatory. Number of tree levels including the leafs and the root.
:config.virtual-block-device.degree:
The trees degree or number of children per inner tree node. The minimum value
is 2 and the maxiumum value 64.
:config.virtual-block-device.nr_of_children:
Mandatory. The tree degree or number of children for each inner node of the
tree.
:config.virtual-block-device.max_lvl:
Highest level index beneath the trees root. Level index 0 is the
leaf level that consists of the encrypted payload-data blocks. A value of
1 is the minimum and results in one inner tree level and a maximum of
[degree^1] leaves. The maximum value is 5 resulting in a maximum of
[degree^5] leaves.
:config.virtual-block-device.nr_of_leafs:
Mandatory. The number of leafs of the tree that are used. This defines the
number of virtual blocks available to the Tresor device. This number must be
less or equal the number of leafs of the tree, which results from the number
of tree levels and the tree degree.
:config.virtual-block-device.num_leaves:
The number of leaves of the tree that are used. This value must
be within the limit defined by [max_level] and [degree].
Considering the above mentioned maxima and the fixed leaf-size of 4Kbyte,
the upper limit for the storage capacity of the container is 4Tbyte .
:config.free-tree:
Mandatory. Contains parameters for the tree that is used for managing the
spare blocks of the Tresor device.
Contains the configuration for the hash tree that forms the journaling buffer
of the Tresor container. This buffer is used for implementing the
Copy-On-Write semantics of the container and keeping snapshots of older
states of the stored data. The buffers capacity is determined by the
number of leaves of this tree and affects how many snapshots can be kept at
a time.
:config.free-tree.nr_of_levels:
Mandatory. Number of tree levels including the leafs and the root.
:config.free-tree.degree:
The trees degree or number of children per inner tree node. The minimum value
is 2 and the maxiumum value 64.
:config.free-tree.nr_of_children:
Mandatory. The tree degree or number of children for each inner node of the
tree.
:config.free-tree.max_lvl:
Highest level index beneath the trees root. Level index 0 is the
leaf level that consists of the buffered blocks. A value of
1 is the minimum and results in one inner tree level and a maximum of
[degree^1] leaves. The maximum value is 5 resulting in a maximum of
[degree^5] leaves.
:config.free-tree.nr_of_leafs:
Mandatory. The number of leafs of the tree that are used. This defines the
number of spare blocks available to the Tresor device. This number must be less
or equal the number of leafs of the tree, which results from the number of
tree levels and the tree degree.
:config.free-tree.num_leaves:
The number of leaves of the tree that are used. This value must
be within the limit defined by [max_level] and [degree].
Considering the above mentioned maxima and the fixed leaf-size of 4Kbyte,
the upper limit for the journaling buffer of the container is 4Tbyte .
Sessions
@ -71,5 +77,5 @@ component apart from the environment sessions:
Examples
~~~~~~~~
An example of how to use the tresor_init component can be found in the test script
'tresor/run/tresor_init_dev.run'.
An example of how to use the tresor_init component can be found in the test
script 'gems/run/tresor_utils.run'.

View File

@ -1,43 +1,23 @@
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="Nr_of_levels">
<xs:restriction base="xs:integer">
<xs:minInclusive value="3"/>
<xs:maxInclusive value="7"/>
</xs:restriction>
</xs:simpleType><!-- Nr_of_levels -->
<xs:simpleType name="Nr_of_children">
<xs:restriction base="xs:integer">
<xs:minInclusive value="2"/>
<xs:maxInclusive value="64"/>
</xs:restriction>
</xs:simpleType><!-- Nr_of_children -->
<xs:element name="config">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="key">
<xs:complexType>
<xs:attribute name="id" type="xs:positiveInteger" />
</xs:complexType>
</xs:element><!-- key -->
<xs:element name="virtual-block-device">
<xs:complexType>
<xs:attribute name="nr_of_levels" type="Nr_of_levels" />
<xs:attribute name="nr_of_children" type="Nr_of_children" />
<xs:attribute name="nr_of_leafs" type="xs:positiveInteger" />
<xs:attribute name="max_lvl" type="xs:positiveInteger" />
<xs:attribute name="degree" type="xs:positiveInteger" />
<xs:attribute name="num_leaves" type="xs:positiveInteger" />
</xs:complexType>
</xs:element><!-- virtual-block-device -->
<xs:element name="free-tree">
<xs:complexType>
<xs:attribute name="nr_of_levels" type="Nr_of_levels" />
<xs:attribute name="nr_of_children" type="Nr_of_children" />
<xs:attribute name="nr_of_leafs" type="xs:positiveInteger" />
<xs:complexType
<xs:attribute name="max_lvl" type="xs:positiveInteger" />
<xs:attribute name="degree" type="xs:positiveInteger" />
<xs:attribute name="num_leaves" type="xs:positiveInteger" />>
</xs:complexType>
</xs:element><!-- free-tree -->

View File

@ -1,92 +0,0 @@
/*
* \brief Integration of the Tresor block encryption
* \author Martin Stein
* \author Josef Soentgen
* \date 2020-11-10
*/
/*
* Copyright (C) 2020 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _TRESOR_INIT__CONFIGURATION_H_
#define _TRESOR_INIT__CONFIGURATION_H_
/* base includes */
#include <util/xml_node.h>
/* tresor includes */
#include <tresor/types.h>
namespace Tresor_init {
using namespace Genode;
using namespace Tresor;
class Configuration;
}
class Tresor_init::Configuration
{
private:
uint64_t _vbd_nr_of_lvls { 0 };
uint64_t _vbd_nr_of_children { 0 };
uint64_t _vbd_nr_of_leafs { 0 };
uint64_t _ft_nr_of_lvls { 0 };
uint64_t _ft_nr_of_children { 0 };
uint64_t _ft_nr_of_leafs { 0 };
public:
struct Invalid : Exception { };
Configuration (Xml_node const &node)
{
node.with_optional_sub_node("virtual-block-device", [&] (Xml_node const &vbd)
{
_vbd_nr_of_lvls = vbd.attribute_value("nr_of_levels", (uint64_t)0);
_vbd_nr_of_children = vbd.attribute_value("nr_of_children", (uint64_t)0);
_vbd_nr_of_leafs = vbd.attribute_value("nr_of_leafs", (uint64_t)0);
});
node.with_optional_sub_node("free-tree", [&] (Xml_node const &ft)
{
_ft_nr_of_lvls = ft.attribute_value("nr_of_levels", (uint64_t)0);
_ft_nr_of_children = ft.attribute_value("nr_of_children", (uint64_t)0);
_ft_nr_of_leafs = ft.attribute_value("nr_of_leafs", (uint64_t)0);
});
ASSERT(_vbd_nr_of_lvls);
ASSERT(_vbd_nr_of_lvls <= TREE_MAX_NR_OF_LEVELS);
ASSERT(_vbd_nr_of_leafs);
ASSERT(is_power_of_2(_vbd_nr_of_children));
ASSERT(_vbd_nr_of_children <= NUM_NODES_PER_BLK);
ASSERT(_ft_nr_of_lvls);
ASSERT(_ft_nr_of_lvls <= TREE_MAX_NR_OF_LEVELS);
ASSERT(_ft_nr_of_leafs);
ASSERT(is_power_of_2(_ft_nr_of_children));
ASSERT(_ft_nr_of_children <= NUM_NODES_PER_BLK);
ASSERT(_ft_nr_of_children <= NUM_NODES_PER_BLK);
}
Configuration (Configuration const &other)
{
_vbd_nr_of_lvls = other._vbd_nr_of_lvls ;
_vbd_nr_of_children = other._vbd_nr_of_children;
_vbd_nr_of_leafs = other._vbd_nr_of_leafs ;
_ft_nr_of_lvls = other._ft_nr_of_lvls ;
_ft_nr_of_children = other._ft_nr_of_children ;
_ft_nr_of_leafs = other._ft_nr_of_leafs ;
}
uint64_t vbd_nr_of_lvls () const { return _vbd_nr_of_lvls ; }
uint64_t vbd_nr_of_children () const { return _vbd_nr_of_children; }
uint64_t vbd_nr_of_leafs () const { return _vbd_nr_of_leafs ; }
uint64_t ft_nr_of_lvls () const { return _ft_nr_of_lvls ; }
uint64_t ft_nr_of_children () const { return _ft_nr_of_children ; }
uint64_t ft_nr_of_leafs () const { return _ft_nr_of_leafs ; }
};
#endif /* _TRESOR_INIT__CONFIGURATION_H_ */

View File

@ -26,9 +26,6 @@
#include <tresor/sb_initializer.h>
#include <tresor/vbd_initializer.h>
/* tresor init includes */
#include <tresor_init/configuration.h>
using namespace Genode;
using namespace Tresor;
@ -50,7 +47,7 @@ class Tresor_init::Main : private Vfs::Env::User, private Crypto_key_files_inter
Attached_rom_dataspace _config_rom { _env, "config" };
Vfs::Simple_env _vfs_env { _env, _heap, _config_rom.xml().sub_node("vfs"), *this };
Signal_handler<Main> _sigh { _env.ep(), *this, &Main::_handle_signal };
Configuration _cfg { _config_rom.xml() };
Superblock_configuration _sb_config { _config_rom.xml() };
Tresor::Path const _crypto_path { _config_rom.xml().sub_node("crypto").attribute_value("path", Tresor::Path()) };
Tresor::Path const _block_io_path { _config_rom.xml().sub_node("block-io").attribute_value("path", Tresor::Path()) };
Tresor::Path const _trust_anchor_path { _config_rom.xml().sub_node("trust-anchor").attribute_value("path", Tresor::Path()) };
@ -70,25 +67,7 @@ class Tresor_init::Main : private Vfs::Env::User, private Crypto_key_files_inter
Vbd_initializer _vbd_initializer { };
Ft_initializer _ft_initializer { };
Sb_initializer _sb_initializer { };
Sb_initializer::Initialize _init_superblocks {{
Tree_configuration {
(Tree_level_index)(_cfg.vbd_nr_of_lvls() - 1),
(Tree_degree)_cfg.vbd_nr_of_children(),
_cfg.vbd_nr_of_leafs()
},
Tree_configuration {
(Tree_level_index)_cfg.ft_nr_of_lvls() - 1,
(Tree_degree)_cfg.ft_nr_of_children(),
_cfg.ft_nr_of_leafs()
},
Tree_configuration {
(Tree_level_index)_cfg.ft_nr_of_lvls() - 1,
(Tree_degree)_cfg.ft_nr_of_children(),
_cfg.ft_nr_of_leafs()
},
_pba_alloc
}};
Sb_initializer::Initialize _init_superblocks { {_sb_config, _pba_alloc} };
Constructible<Crypto_key> &_crypto_key(Key_id key_id)
{
for (Constructible<Crypto_key> &key : _crypto_keys)

View File

@ -18,9 +18,6 @@
#include <timer_session/connection.h>
#include <vfs/simple_env.h>
/* tresor init includes */
#include <tresor_init/configuration.h>
/* tresor includes */
#include <tresor/crypto.h>
#include <tresor/trust_anchor.h>
@ -270,7 +267,7 @@ struct Tresor_tester::Command : Avl_node<Command>, Schedule<Command>::Item
Constructible<Initialize_trust_anchor_node> init_trust_anchor_node { };
Constructible<Start_benchmark_node> start_benchmark_node { };
Constructible<Log_node> log_node { };
Constructible<Tresor_init::Configuration> initialize_config { };
Constructible<Tresor::Superblock_configuration> sb_config { };
Trust_anchor::Initialize *init_trust_anchor_ptr { };
Sb_initializer::Initialize *init_superblocks_ptr { };
Sb_check::Check *check_superblocks_ptr { };
@ -342,7 +339,7 @@ struct Tresor_tester::Command : Avl_node<Command>, Schedule<Command>::Item
Command(Xml_node const &node, Id id) : type(type_from_node(node)), id(id)
{
switch (type) {
case INITIALIZE: initialize_config.construct(node); break;
case INITIALIZE: sb_config.construct(node); break;
case REQUEST: request_node.construct(node); break;
case INIT_TRUST_ANCHOR: init_trust_anchor_node.construct(node); break;
case START_BENCHMARK: start_benchmark_node.construct(node); break;
@ -589,25 +586,7 @@ class Tresor_tester::Main : Vfs::Env::User, Client_data_interface, Crypto_key_fi
case Command::INIT:
{
_reset_snap_refs();
Tresor_init::Configuration const &cfg { *cmd.initialize_config };
cmd.init_superblocks_ptr = new (_heap) Sb_initializer::Initialize({
Tree_configuration {
(Tree_level_index)(cfg.vbd_nr_of_lvls() - 1),
(Tree_degree)cfg.vbd_nr_of_children(),
cfg.vbd_nr_of_leafs()
},
Tree_configuration {
(Tree_level_index)cfg.ft_nr_of_lvls() - 1,
(Tree_degree)cfg.ft_nr_of_children(),
cfg.ft_nr_of_leafs()
},
Tree_configuration {
(Tree_level_index)cfg.ft_nr_of_lvls() - 1,
(Tree_degree)cfg.ft_nr_of_children(),
cfg.ft_nr_of_leafs()
},
_pba_alloc
});
cmd.init_superblocks_ptr = new (_heap) Sb_initializer::Initialize({ *cmd.sb_config, _pba_alloc });
_mark_command_in_progress(cmd, progress);
break;
}

View File

@ -3,7 +3,6 @@ TARGET := tresor_tester
SRC_CC += main.cc
INC_DIR += $(PRG_DIR)
INC_DIR += $(REP_DIR)/src/app/tresor_init/include
LIBS += base
LIBS += tresor

View File

@ -249,7 +249,7 @@ void Free_tree::Extend_tree::_generate_write_blk_req(bool &progress)
bool Free_tree::Extend_tree::_add_new_root_lvl()
{
if (_attr.in_out_ft.max_lvl >= TREE_MAX_LEVEL)
if (_attr.in_out_ft.max_lvl >= TREE_MAX_MAX_LEVEL)
return false;
_attr.in_out_ft.max_lvl++;

View File

@ -40,7 +40,7 @@ bool Ft_initializer::Initialize::execute(Block_io &block_io)
case INIT:
_num_remaining_leaves = _attr.in_tree_cfg.num_leaves;
for (Tree_level_index lvl = 0; lvl < TREE_MAX_LEVEL; lvl++)
for (Tree_level_index lvl = 0; lvl < TREE_MAX_MAX_LEVEL; lvl++)
_reset_level(lvl, DONE);
_t1_node_states[_attr.in_tree_cfg.max_lvl + 1][0] = INIT_BLOCK;

View File

@ -80,9 +80,9 @@ class Tresor::Free_tree::Allocate_pbas : Noncopyable
Tree_walk_generations _old_generations { };
Number_of_blocks _num_pbas { 0 };
Block _blk { };
Tree_node_index _node_idx[TREE_MAX_NR_OF_LEVELS] { };
Tree_node_index _node_idx[TREE_MAX_NR_OF_LEVELS + 1] { };
bool _apply_allocation { false };
Type_1_node_block _t1_blks[TREE_MAX_NR_OF_LEVELS] { };
Type_1_node_block _t1_blks[TREE_MAX_NR_OF_LEVELS + 1] { };
Type_2_node_block _t2_blk { };
Tree_degree_log_2 _vbd_degree_log_2 { 0 };
Tree_level_index _lvl { 0 };
@ -144,7 +144,7 @@ class Tresor::Free_tree::Extend_tree : Noncopyable
Tree_walk_pbas _new_pbas { };
Tree_level_index _lvl { 0 };
Block _blk { };
Type_1_node_block _t1_blks[TREE_MAX_NR_OF_LEVELS] { };
Type_1_node_block _t1_blks[TREE_MAX_NR_OF_LEVELS + 1] { };
Type_2_node_block _t2_blk { };
Tree_level_index _alloc_lvl { 0 };
Physical_block_address _alloc_pba { 0 };

View File

@ -50,7 +50,7 @@ class Tresor::Ft_initializer : Noncopyable
Attr const _attr;
Type_2_node_block _t2_blk { };
Type_1_node_block_walk _t1_blks { };
Node_state _t1_node_states[TREE_MAX_NR_OF_LEVELS][NUM_NODES_PER_BLK] { };
Node_state _t1_node_states[TREE_MAX_NR_OF_LEVELS + 1][NUM_NODES_PER_BLK] { };
Node_state _t2_node_states[NUM_NODES_PER_BLK] { };
Number_of_leaves _num_remaining_leaves { 0 };
Block _blk { };

View File

@ -53,8 +53,8 @@ class Tresor::Meta_tree::Allocate_pba : Noncopyable
Helper _helper;
Attr const _attr;
Block _blk { };
Tree_node_index _node_idx[TREE_MAX_NR_OF_LEVELS] { };
Type_1_node_block _t1_blks[TREE_MAX_NR_OF_LEVELS] { };
Tree_node_index _node_idx[TREE_MAX_NR_OF_LEVELS + 1] { };
Type_1_node_block _t1_blks[TREE_MAX_NR_OF_LEVELS + 1] { };
Type_2_node_block _t2_blk { };
Tree_level_index _lvl { 0 };
Generatable_request<Helper, State, Block_io::Read> _read_block { };

View File

@ -36,9 +36,7 @@ class Tresor::Sb_initializer : Noncopyable
struct Attr
{
Tree_configuration const in_vbd_cfg;
Tree_configuration const in_ft_cfg;
Tree_configuration const in_mt_cfg;
Superblock_configuration const &in_sb_cfg;
Pba_allocator &in_out_pba_alloc;
};

View File

@ -16,6 +16,8 @@
#define _TRESOR__TYPES_H_
/* base includes */
#include <util/xml_node.h>
#include <util/xml_generator.h>
#include <util/reconstructible.h>
/* os includes */
@ -65,8 +67,11 @@ namespace Tresor {
enum { NUM_NODES_PER_BLK = (size_t)BLOCK_SIZE / (size_t)ON_DISC_NODE_SIZE };
enum { TREE_MAX_DEGREE_LOG_2 = 6 };
enum { TREE_MAX_DEGREE = 1 << TREE_MAX_DEGREE_LOG_2 };
enum { TREE_MAX_LEVEL = 6 };
enum { TREE_MAX_NR_OF_LEVELS = TREE_MAX_LEVEL + 1 };
enum { TREE_MIN_DEGREE_LOG_2 = 1 };
enum { TREE_MIN_DEGREE = 1 << TREE_MIN_DEGREE_LOG_2 };
enum { TREE_MIN_MAX_LEVEL = 1 };
enum { TREE_MAX_MAX_LEVEL = 5 };
enum { TREE_MAX_NR_OF_LEVELS = TREE_MAX_MAX_LEVEL + 1 };
enum { KEY_SIZE = 32 };
enum { MAX_NR_OF_SNAPSHOTS = 48 };
enum { MAX_SNAP_IDX = MAX_NR_OF_SNAPSHOTS - 1 };
@ -74,10 +79,8 @@ namespace Tresor {
enum { SNAPSHOT_STORAGE_SIZE = 72 };
enum { NR_OF_SUPERBLOCK_SLOTS = 8 };
enum { MAX_SUPERBLOCK_INDEX = NR_OF_SUPERBLOCK_SLOTS - 1 };
enum { FREE_TREE_MIN_MAX_LEVEL = 2 };
enum { TREE_MAX_NR_OF_LEAVES = to_the_power_of<Number_of_leaves>(TREE_MAX_DEGREE, (TREE_MAX_LEVEL - 1)) };
enum { INVALID_VBA = to_the_power_of<Virtual_block_address>(TREE_MAX_DEGREE, TREE_MAX_LEVEL - 1) };
enum { TREE_MIN_DEGREE = 1 };
enum { TREE_MAX_NR_OF_LEAVES = to_the_power_of<Number_of_leaves>(TREE_MAX_DEGREE, (TREE_MAX_MAX_LEVEL - 1)) };
enum { INVALID_VBA = to_the_power_of<Virtual_block_address>(TREE_MAX_DEGREE, TREE_MAX_MAX_LEVEL - 1) };
struct Byte_range;
struct Key_value;
@ -88,6 +91,7 @@ namespace Tresor {
struct Block_generator;
struct Superblock;
struct Superblock_info;
struct Superblock_configuration;
struct Snapshot;
struct Snapshots_info;
struct Snapshots;
@ -606,9 +610,57 @@ struct Tresor::Tree_root
struct Tresor::Tree_configuration
{
Tree_level_index max_lvl;
Tree_degree degree;
Number_of_leaves num_leaves;
Tree_level_index const max_lvl;
Tree_degree const degree;
Number_of_leaves const num_leaves;
void assert_valid() const
{
ASSERT(max_lvl >= TREE_MIN_MAX_LEVEL);
ASSERT(max_lvl <= TREE_MAX_MAX_LEVEL);
ASSERT(degree <= TREE_MAX_DEGREE);
ASSERT(degree >= TREE_MIN_DEGREE);
ASSERT(is_power_of_2(degree));
ASSERT(num_leaves);
ASSERT(num_leaves <= tree_max_max_vba(degree, max_lvl) + 1);
}
Tree_configuration(Tree_level_index max_lvl, Tree_degree degree, Number_of_leaves num_leaves)
: max_lvl(max_lvl), degree(degree), num_leaves(num_leaves) { assert_valid(); }
Tree_configuration(Xml_node const &node)
:
max_lvl(node.attribute_value("max_lvl", (Tree_level_index)0)),
degree(node.attribute_value("degree", (Tree_degree)0)),
num_leaves(node.attribute_value("num_leaves", (Number_of_leaves)0))
{ assert_valid(); }
};
struct Tresor::Superblock_configuration
{
Tree_configuration const vbd;
Tree_configuration const free_tree;
Superblock_configuration(Tree_configuration const &vbd, Tree_configuration const &free_tree)
: vbd(vbd), free_tree(free_tree) { }
Superblock_configuration(Xml_node const &node)
: vbd(node.sub_node("virtual-block-device")), free_tree(node.sub_node("free-tree")) { }
void generate_xml(Xml_generator &xml)
{
xml.node("virtual-block-device", [&] () {
xml.attribute("max_lvl", vbd.max_lvl);
xml.attribute("degree", vbd.degree);
xml.attribute("num_leaves", vbd.num_leaves);
});
xml.node("free-tree", [&] () {
xml.attribute("max_lvl", free_tree.max_lvl);
xml.attribute("degree", free_tree.degree);
xml.attribute("num_leaves", free_tree.num_leaves);
});
}
};
@ -634,7 +686,7 @@ struct Tresor::Type_1_node_block
struct Tresor::Type_1_node_block_walk
{
Type_1_node_block items[TREE_MAX_NR_OF_LEVELS] { };
Type_1_node_block items[TREE_MAX_NR_OF_LEVELS + 1] { };
Type_1_node &node(Virtual_block_address vba, Tree_level_index lvl, Tree_degree degr)
{
@ -721,7 +773,7 @@ struct Tresor::Snapshot
Physical_block_address pba { INVALID_PBA };
Generation gen { MAX_GENERATION };
Number_of_leaves nr_of_leaves { TREE_MAX_NR_OF_LEAVES };
Tree_level_index max_level { TREE_MAX_LEVEL };
Tree_level_index max_level { TREE_MAX_MAX_LEVEL };
bool valid { false };
Snapshot_id id { MAX_SNAP_ID };
bool keep { false };
@ -1037,12 +1089,12 @@ struct Tresor::Superblock
struct Tresor::Type_1_node_walk
{
Type_1_node nodes[TREE_MAX_NR_OF_LEVELS] { };
Type_1_node nodes[TREE_MAX_NR_OF_LEVELS + 1] { };
void print(Output &out) const
{
bool first { true };
for (unsigned idx { 0 }; idx < TREE_MAX_NR_OF_LEVELS; idx++) {
for (unsigned idx { 0 }; idx <= TREE_MAX_NR_OF_LEVELS + 1; idx++) {
if (!nodes[idx].valid())
continue;
@ -1056,12 +1108,12 @@ struct Tresor::Type_1_node_walk
struct Tresor::Tree_walk_pbas
{
Physical_block_address pbas[TREE_MAX_NR_OF_LEVELS] { 0 };
Physical_block_address pbas[TREE_MAX_NR_OF_LEVELS + 1] { 0 };
void print(Output &out) const
{
bool first { true };
for (unsigned idx { 0 }; idx < TREE_MAX_NR_OF_LEVELS; idx++) {
for (unsigned idx { 0 }; idx < TREE_MAX_NR_OF_LEVELS + 1; idx++) {
if (!pbas[idx])
continue;
@ -1075,7 +1127,7 @@ struct Tresor::Tree_walk_pbas
struct Tresor::Tree_walk_generations
{
Generation items[TREE_MAX_NR_OF_LEVELS] { };
Generation items[TREE_MAX_NR_OF_LEVELS + 1] { };
};
@ -1154,7 +1206,7 @@ class Tresor::Pba_allocation {
void print(Output &out) const
{
bool first { true };
for (unsigned lvl { 0 }; lvl < TREE_MAX_NR_OF_LEVELS; lvl++) {
for (unsigned lvl { 0 }; lvl < TREE_MAX_NR_OF_LEVELS + 1; lvl++) {
if (_t1_node_walk.nodes[lvl].pba == _new_pbas.pbas[lvl])
continue;
@ -1165,5 +1217,4 @@ class Tresor::Pba_allocation {
}
};
#endif /* _TRESOR__TYPES_H_ */

View File

@ -37,7 +37,7 @@ struct Tresor::Vbd_check : Noncopyable
Request_helper<Check, State> _helper;
Attr const _attr;
Type_1_node_block_walk _t1_blks { };
bool _check_node[TREE_MAX_NR_OF_LEVELS][NUM_NODES_PER_BLK] { };
bool _check_node[TREE_MAX_NR_OF_LEVELS + 1][NUM_NODES_PER_BLK] { };
Block _blk { };
Number_of_leaves _num_remaining_leaves { 0 };
Generatable_request<Request_helper<Check, State>, State, Block_io::Read> _read_block { };

View File

@ -49,7 +49,7 @@ class Tresor::Vbd_initializer : Noncopyable
Helper _helper;
Attr const _attr;
Type_1_node_block_walk _t1_blks { };
Node_state _node_states[TREE_MAX_NR_OF_LEVELS][NUM_NODES_PER_BLK] { DONE };
Node_state _node_states[TREE_MAX_NR_OF_LEVELS + 1][NUM_NODES_PER_BLK] { DONE };
bool _generated_req_success { false };
Block _blk { };
Number_of_leaves _num_remaining_leaves { };

View File

@ -106,6 +106,7 @@ void Meta_tree::Allocate_pba::_alloc_pba_of(Type_2_node &t2_node, Physical_block
t2_node.reserved = false;
}
void Meta_tree::Allocate_pba::_traverse_curr_node(bool &progress)
{
if (_lvl) {

View File

@ -23,14 +23,12 @@ void Sb_check::Check::_check_snap(bool &progress)
if (!snap.valid) {
_helper.state = CHECK_VBD_SUCCEEDED;
progress = true;
if (VERBOSE_CHECK)
log(" skip snap ", _snap_idx, " as it is unused");
return;
}
_tree_root.construct(snap.pba, snap.gen, snap.hash, snap.max_level, _sb.degree, snap.nr_of_leaves);
_check_vbd.generate(_helper, CHECK_VBD, CHECK_VBD_SUCCEEDED, progress, *_tree_root);
if (VERBOSE_CHECK)
log(" check snap ", _snap_idx, " (", snap, ")");
log(" check snap #", _snap_idx, " (", snap, ")");
}
@ -55,7 +53,7 @@ bool Sb_check::Check::execute(Vbd_check &vbd_check, Ft_check &ft_check, Block_io
if (check_hash(_blk, _hash)) {
_sb.decode_from_blk(_blk);
if (VERBOSE_CHECK)
log("check superblock ", _sb_idx, " hash ", _hash, "\n read superblock");
log("check superblock (pba ", _sb_idx, " hash ", _hash, ")");
if (!_sb.valid()) {
_helper.mark_failed(progress, "superblock marked invalid");;
@ -81,7 +79,7 @@ bool Sb_check::Check::execute(Vbd_check &vbd_check, Ft_check &ft_check, Block_io
_tree_root.construct(_sb.free_number, _sb.free_gen, _sb.free_hash, _sb.free_max_level, _sb.free_degree, _sb.free_leaves);
_check_ft.generate(_helper, CHECK_FT, CHECK_FT_SUCCEEDED, progress, *_tree_root);
if (VERBOSE_CHECK)
log(" check free tree");
log(" check free tree (", _tree_root->t1_node(), ")");
}
break;
@ -91,7 +89,7 @@ bool Sb_check::Check::execute(Vbd_check &vbd_check, Ft_check &ft_check, Block_io
_tree_root.construct(_sb.meta_number, _sb.meta_gen, _sb.meta_hash, _sb.meta_max_level, _sb.meta_degree, _sb.meta_leaves);
_check_ft.generate(_helper, CHECK_MT, CHECK_MT_SUCCEEDED, progress, *_tree_root);
if (VERBOSE_CHECK)
log(" check meta tree");
log(" check meta tree (", _tree_root->t1_node(), ")");
break;
case CHECK_MT: progress |= _check_ft.execute(ft_check, block_io); break;

View File

@ -24,19 +24,19 @@ bool Sb_initializer::Initialize::execute(Block_io &block_io, Trust_anchor &trust
switch (_helper.state) {
case INIT:
{
_init_vbd.generate(_helper, INIT_VBD, INIT_VBD_SUCCEEDED, progress, _attr.in_vbd_cfg, _vbd_root, _attr.in_out_pba_alloc);
_init_vbd.generate(_helper, INIT_VBD, INIT_VBD_SUCCEEDED, progress, _attr.in_sb_cfg.vbd, _vbd_root, _attr.in_out_pba_alloc);
break;
}
case INIT_VBD: progress |= _init_vbd.execute(vbd_initializer, block_io); break;
case INIT_VBD_SUCCEEDED:
_init_ft.generate(_helper, INIT_FT, INIT_FT_SUCCEEDED, progress, _attr.in_ft_cfg, _ft_root, _attr.in_out_pba_alloc);
_init_ft.generate(_helper, INIT_FT, INIT_FT_SUCCEEDED, progress, _attr.in_sb_cfg.free_tree, _ft_root, _attr.in_out_pba_alloc);
break;
case INIT_FT: progress |= _init_ft.execute(ft_initializer, block_io); break;
case INIT_FT_SUCCEEDED:
_init_ft.generate(_helper, INIT_FT, INIT_MT_SUCCEEDED, progress, _attr.in_mt_cfg, _mt_root, _attr.in_out_pba_alloc);
_init_ft.generate(_helper, INIT_FT, INIT_MT_SUCCEEDED, progress, _attr.in_sb_cfg.free_tree, _mt_root, _attr.in_out_pba_alloc);
break;
case INIT_MT_SUCCEEDED:
@ -57,27 +57,27 @@ bool Sb_initializer::Initialize::execute(Block_io &block_io, Trust_anchor &trust
snap.pba = _vbd_root.pba;
snap.gen = _vbd_root.gen;
snap.hash = _vbd_root.hash;
snap.nr_of_leaves = _attr.in_vbd_cfg.num_leaves;
snap.max_level = _attr.in_vbd_cfg.max_lvl;
snap.nr_of_leaves = _attr.in_sb_cfg.vbd.num_leaves;
snap.max_level = _attr.in_sb_cfg.vbd.max_lvl;
snap.valid = true;
snap.id = 0;
_sb.current_key.id = 1;
_sb.state = Superblock::NORMAL;
_sb.degree = _attr.in_vbd_cfg.degree;
_sb.degree = _attr.in_sb_cfg.vbd.degree;
_sb.first_pba = _attr.in_out_pba_alloc.first_pba() - NR_OF_SUPERBLOCK_SLOTS;
_sb.nr_of_pbas = _attr.in_out_pba_alloc.num_used_pbas() + NR_OF_SUPERBLOCK_SLOTS;
_sb.free_number = _ft_root.pba;
_sb.free_gen = _ft_root.gen;
_sb.free_hash = _ft_root.hash;
_sb.free_max_level = _attr.in_ft_cfg.max_lvl;
_sb.free_degree = _attr.in_ft_cfg.degree;
_sb.free_leaves = _attr.in_ft_cfg.num_leaves;
_sb.free_max_level = _attr.in_sb_cfg.free_tree.max_lvl;
_sb.free_degree = _attr.in_sb_cfg.free_tree.degree;
_sb.free_leaves = _attr.in_sb_cfg.free_tree.num_leaves;
_sb.meta_number = _mt_root.pba;
_sb.meta_gen = _mt_root.gen;
_sb.meta_hash = _mt_root.hash;
_sb.meta_max_level = _attr.in_mt_cfg.max_lvl;
_sb.meta_degree = _attr.in_mt_cfg.degree;
_sb.meta_leaves = _attr.in_mt_cfg.num_leaves;
_sb.meta_max_level = _attr.in_sb_cfg.free_tree.max_lvl;
_sb.meta_degree = _attr.in_sb_cfg.free_tree.degree;
_sb.meta_leaves = _attr.in_sb_cfg.free_tree.num_leaves;
_sb.encode_to_blk(_blk);
_write_block.generate(_helper, WRITE_BLK, WRITE_BLK_SUCCEEDED, progress, _sb_idx, _blk);
break;

View File

@ -50,6 +50,10 @@ bool Superblock_control::Write_vbas::execute(Execute_attr const &attr)
switch (_helper.state) {
case INIT:
if (!_attr.in_num_vbas) {
_helper.mark_failed(progress, "number of blocks is 0");
break;
}
if (_attr.in_first_vba + _attr.in_num_vbas - 1 > attr.sb.max_vba()) {
_helper.mark_failed(progress, "invalid VBA range");
break;
@ -60,9 +64,9 @@ bool Superblock_control::Write_vbas::execute(Execute_attr const &attr)
case WRITE_VBA: progress |= _write_vba.execute(attr.vbd, attr.client_data, attr.block_io, attr.free_tree, attr.meta_tree, attr.crypto); break;
case WRITE_VBA_SUCCEEDED:
if (++_num_written_vbas < _attr.in_num_vbas) {
if (++_num_written_vbas < _attr.in_num_vbas)
_start_write_vba(attr, progress);
} else
else
_helper.mark_succeeded(progress);
break;
@ -93,6 +97,10 @@ bool Superblock_control::Read_vbas::execute(Execute_attr const &attr)
switch (_helper.state) {
case INIT:
if (!_attr.in_num_vbas) {
_helper.mark_failed(progress, "number of blocks is 0");
break;
}
if (_attr.in_first_vba + _attr.in_num_vbas - 1 > attr.sb.max_vba()) {
_helper.mark_failed(progress, "invalid VBA range");
break;
@ -103,9 +111,9 @@ bool Superblock_control::Read_vbas::execute(Execute_attr const &attr)
case READ_VBA: progress |= _read_vba.execute(attr.vbd, attr.client_data, attr.block_io, attr.crypto); break;
case READ_VBA_SUCCEEDED:
if (++_num_read_vbas < _attr.in_num_vbas) {
if (++_num_read_vbas < _attr.in_num_vbas)
_start_read_vba(attr, progress);
} else
else
_helper.mark_succeeded(progress);
break;

View File

@ -101,7 +101,7 @@ bool Vbd_initializer::Initialize::execute(Block_io &block_io)
case INIT:
_num_remaining_leaves = _attr.in_tree_cfg.num_leaves;
for (Tree_level_index lvl = 0; lvl < TREE_MAX_LEVEL; lvl++)
for (Tree_level_index lvl = 1; lvl < TREE_MAX_MAX_LEVEL; lvl++)
_reset_level(lvl, Vbd_initializer::Initialize::DONE);
_node_states[_attr.in_tree_cfg.max_lvl + 1][0] = Vbd_initializer::Initialize::INIT_BLOCK;
@ -111,7 +111,7 @@ bool Vbd_initializer::Initialize::execute(Block_io &block_io)
case EXECUTE_NODES:
for (Tree_level_index lvl = 0; lvl <= _attr.in_tree_cfg.max_lvl + 1; lvl++)
for (Tree_level_index lvl = 1; lvl <= _attr.in_tree_cfg.max_lvl + 1; lvl++)
for (Tree_node_index node_idx = 0; node_idx < _attr.in_tree_cfg.degree; node_idx++)
if (_execute_node(lvl, node_idx, progress))
return progress;

View File

@ -642,7 +642,7 @@ 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 };
if (snap[idx].max_level >= TREE_MAX_LEVEL)
if (snap[idx].max_level >= TREE_MAX_MAX_LEVEL)
return false;
Tree_level_index new_lvl { snap[old_idx].max_level + 1 };