diff --git a/src/crimson/os/seastore/onode_manager/staged-fltree/value.cc b/src/crimson/os/seastore/onode_manager/staged-fltree/value.cc index 3d9538d55aa..bfaba92b4dc 100644 --- a/src/crimson/os/seastore/onode_manager/staged-fltree/value.cc +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/value.cc @@ -115,6 +115,44 @@ void validate_tree_config(const tree_conf_t& conf) ceph_assert(conf.internal_node_size % DISK_BLOCK_SIZE == 0); ceph_assert(conf.leaf_node_size <= MAX_NODE_SIZE); ceph_assert(conf.leaf_node_size % DISK_BLOCK_SIZE == 0); + + if (conf.do_split_check) { + // In hope to comply with 3 * (oid + ns) + 2 * value < node + // + // see node_layout.h for NODE_BLOCK_SIZE considerations + // + // The below calculations also consider the internal indexing overhead in + // order to be accurate, so the equation has become: + // node-header-size + 2 * max-full-insert-size + + // max-ns/oid-split-overhead <= node-size + + auto obj = ghobject_t{shard_id_t{0}, 0, 0, "", "", 0, 0}; + key_hobj_t key(obj); + auto max_str_size = conf.max_ns_size + conf.max_oid_size; +#define _STAGE_T(NodeType) node_to_stage_t +#define NXT_T(StageType) staged + + laddr_t i_value{0}; + auto insert_size_2 = + _STAGE_T(InternalNode0)::template insert_size(key, i_value); + auto insert_size_0 = + NXT_T(NXT_T(_STAGE_T(InternalNode0)))::template insert_size(key, i_value); + unsigned internal_size_bound = sizeof(node_header_t) + + (insert_size_2 + max_str_size) * 2 + + (insert_size_2 - insert_size_0 + max_str_size); + ceph_assert(internal_size_bound <= conf.internal_node_size); + + value_config_t l_value; + l_value.payload_size = conf.max_value_payload_size; + insert_size_2 = + _STAGE_T(LeafNode0)::template insert_size(key, l_value); + insert_size_0 = + NXT_T(NXT_T(_STAGE_T(LeafNode0)))::template insert_size(key, l_value); + unsigned leaf_size_bound = sizeof(node_header_t) + + (insert_size_2 + max_str_size) * 2 + + (insert_size_2 - insert_size_0 + max_str_size); + ceph_assert(leaf_size_bound <= conf.leaf_node_size); + } } } diff --git a/src/crimson/os/seastore/onode_manager/staged-fltree/value.h b/src/crimson/os/seastore/onode_manager/staged-fltree/value.h index f91468d0432..2aa7ee8d40f 100644 --- a/src/crimson/os/seastore/onode_manager/staged-fltree/value.h +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/value.h @@ -162,6 +162,7 @@ struct tree_conf_t { value_size_t max_value_payload_size; extent_len_t internal_node_size; extent_len_t leaf_node_size; + bool do_split_check = true; }; class tree_cursor_t; diff --git a/src/test/crimson/seastore/onode_tree/test_value.h b/src/test/crimson/seastore/onode_tree/test_value.h index cb509363837..42795529b6d 100644 --- a/src/test/crimson/seastore/onode_tree/test_value.h +++ b/src/test/crimson/seastore/onode_tree/test_value.h @@ -41,7 +41,8 @@ template + extent_len_t LEAF_NODE_SIZE, + bool DO_SPLIT_CHECK> class TestValue final : public Value { public: static constexpr tree_conf_t TREE_CONF = { @@ -50,7 +51,8 @@ class TestValue final : public Value { MAX_OID_SIZE, MAX_VALUE_PAYLOAD_SIZE, INTERNAL_NODE_SIZE, - LEAF_NODE_SIZE + LEAF_NODE_SIZE, + DO_SPLIT_CHECK }; using id_t = test_item_t::id_t; @@ -201,8 +203,8 @@ class TestValue final : public Value { }; using UnboundedValue = TestValue< - value_magic_t::TEST_UNBOUND, 4096, 4096, 4096, 4096, 4096>; + value_magic_t::TEST_UNBOUND, 4096, 4096, 4096, 4096, 4096, false>; using BoundedValue = TestValue< - value_magic_t::TEST_BOUNDED, 320, 320, 640, 4096, 4096>; + value_magic_t::TEST_BOUNDED, 320, 320, 640, 4096, 4096, true>; }