]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
crimson/onode-staged-tree: add and use node sizes in tree_conf_t
authorYingxin Cheng <yingxin.cheng@intel.com>
Wed, 2 Jun 2021 05:33:50 +0000 (13:33 +0800)
committerYingxin Cheng <yingxin.cheng@intel.com>
Fri, 11 Jun 2021 14:43:58 +0000 (22:43 +0800)
Signed-off-by: Yingxin Cheng <yingxin.cheng@intel.com>
src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.h
src/crimson/os/seastore/onode_manager/staged-fltree/fwd.h
src/crimson/os/seastore/onode_manager/staged-fltree/node.cc
src/crimson/os/seastore/onode_manager/staged-fltree/node_extent_accessor.h
src/crimson/os/seastore/onode_manager/staged-fltree/node_extent_manager.h
src/crimson/os/seastore/onode_manager/staged-fltree/node_extent_manager/dummy.h
src/crimson/os/seastore/onode_manager/staged-fltree/node_extent_manager/seastore.h
src/crimson/os/seastore/onode_manager/staged-fltree/node_layout.h
src/crimson/os/seastore/onode_manager/staged-fltree/value.cc
src/crimson/os/seastore/onode_manager/staged-fltree/value.h
src/test/crimson/seastore/onode_tree/test_value.h

index d075364af19933f63eb8d3ca5af128d442db1627..1444ebbb6d0886adcaa17b9dbf7b6fa253d1f6a0 100644 (file)
@@ -14,7 +14,9 @@ struct FLTreeOnode final : Onode, Value {
     value_magic_t::ONODE,
     128,        // max_ns_size
     320,        // max_oid_size
-    1200        // max_value_payload_size
+    1200,       // max_value_payload_size
+    4096,       // internal_node_size
+    4096        // leaf_node_size
   };
 
   enum class status_t {
index 741c31efe1dfcbe750525e06cdc22a085a9aff2d..2c08895320da6643bb1e568798cd9b7c8817e1ce 100644 (file)
@@ -59,10 +59,12 @@ constexpr auto INDEX_LAST = INDEX_END - 0x4;
 constexpr auto INDEX_UPPER_BOUND = INDEX_END - 0x8;
 inline bool is_valid_index(index_t index) { return index < INDEX_UPPER_BOUND; }
 
-// TODO: decide by NODE_BLOCK_SIZE
+// we support up to 64 KiB tree nodes
 using node_offset_t = uint16_t;
 constexpr node_offset_t DISK_BLOCK_SIZE = 1u << 12;
 constexpr node_offset_t NODE_BLOCK_SIZE = DISK_BLOCK_SIZE * 1u;
+constexpr auto MAX_NODE_SIZE =
+    (extent_len_t)std::numeric_limits<node_offset_t>::max() + 1;
 
 using string_size_t = uint16_t;
 
index 9fcd950107eaf1ba563498362cdc4bd8a35a5292..d0f35817f59d8765948d14c24d6cd934cf2613a8 100644 (file)
@@ -653,11 +653,7 @@ eagain_future<Ref<Node>> Node::load(
     context_t c, laddr_t addr, bool expect_is_level_tail)
 {
   LOG_PREFIX(OTree::Node::load);
-  // NOTE:
-  // *option1: all types of node have the same length;
-  // option2: length is defined by node/field types;
-  // option3: length is totally flexible;
-  return c.nm.read_extent(c.t, addr, NODE_BLOCK_SIZE
+  return c.nm.read_extent(c.t, addr
   ).handle_error(
     eagain_ertr::pass_further{},
     crimson::ct_error::input_output_error::handle(
@@ -684,12 +680,20 @@ eagain_future<Ref<Node>> Node::load(
              c.t, addr, expect_is_level_tail);
       ceph_abort("fatal error");
     })
-  ).safe_then([expect_is_level_tail](auto extent) {
+  ).safe_then([FNAME, c, expect_is_level_tail](auto extent) {
     auto [node_type, field_type] = extent->get_types();
     if (node_type == node_type_t::LEAF) {
+      if (extent->get_length() != c.vb.get_leaf_node_size()) {
+        ERRORT("leaf length mismatch -- {}", c.t, extent);
+        ceph_abort("fatal error");
+      }
       auto impl = LeafNodeImpl::load(extent, field_type, expect_is_level_tail);
       return Ref<Node>(new LeafNode(impl.get(), std::move(impl)));
     } else if (node_type == node_type_t::INTERNAL) {
+      if (extent->get_length() != c.vb.get_internal_node_size()) {
+        ERRORT("internal length mismatch -- {}", c.t, extent);
+        ceph_abort("fatal error");
+      }
       auto impl = InternalNodeImpl::load(extent, field_type, expect_is_level_tail);
       return Ref<Node>(new InternalNode(impl.get(), std::move(impl)));
     } else {
index ec42c4f569e1842990603b0012d8c36a3f54cb7e..ab1b1880f3555ac6f0aebab31dcae763f29338e7 100644 (file)
@@ -503,13 +503,14 @@ class NodeExtentAccessorT {
       return eagain_ertr::make_ready_future<NodeExtentMutable>(*mut);
     }
     assert(!extent->is_initial_pending());
-    return c.nm.alloc_extent(c.t, node_stage_t::EXTENT_SIZE
+    auto alloc_size = extent->get_length();
+    return c.nm.alloc_extent(c.t, alloc_size
     ).handle_error(
       eagain_ertr::pass_further{},
       crimson::ct_error::input_output_error::handle(
-          [FNAME, c, l_to_discard = extent->get_laddr()] {
+          [FNAME, c, alloc_size, l_to_discard = extent->get_laddr()] {
         ERRORT("EIO during allocate -- node_size={}, to_discard={:x}",
-               c.t, node_stage_t::EXTENT_SIZE, l_to_discard);
+               c.t, alloc_size, l_to_discard);
         ceph_abort("fatal error");
       })
     ).safe_then([this, c, FNAME] (auto fresh_extent) {
index 4304f0ed51e0737d74c83d255d1fd32bd4375b07..ac3b7179cf8b52958be55f33a80dc089d3a81ebc 100644 (file)
@@ -68,7 +68,7 @@ class NodeExtentManager {
     crimson::ct_error::enoent,
     crimson::ct_error::erange>;
   virtual read_ertr::future<NodeExtentRef> read_extent(
-      Transaction&, laddr_t, extent_len_t) = 0;
+      Transaction&, laddr_t) = 0;
 
   using alloc_ertr = base_ertr;
   virtual alloc_ertr::future<NodeExtentRef> alloc_extent(
index c868d4448bb56445a37533cd3059b44043426b88..1cdb117c0a089a2d62871c8ab39ea50d3d6eb607 100644 (file)
@@ -75,14 +75,14 @@ class DummyNodeExtentManager final: public NodeExtentManager {
   bool is_read_isolated() const override { return false; }
 
   read_ertr::future<NodeExtentRef> read_extent(
-      Transaction& t, laddr_t addr, extent_len_t len) override {
-    TRACET("reading {}B at {:#x} ...", t, len, addr);
+      Transaction& t, laddr_t addr) override {
+    TRACET("reading at {:#x} ...", t, addr);
     if constexpr (SYNC) {
-      return read_extent_sync(t, addr, len);
+      return read_extent_sync(t, addr);
     } else {
       using namespace std::chrono_literals;
-      return seastar::sleep(1us).then([this, &t, addr, len] {
-        return read_extent_sync(t, addr, len);
+      return seastar::sleep(1us).then([this, &t, addr] {
+        return read_extent_sync(t, addr);
       });
     }
   }
@@ -133,13 +133,12 @@ class DummyNodeExtentManager final: public NodeExtentManager {
 
  private:
   read_ertr::future<NodeExtentRef> read_extent_sync(
-      Transaction& t, laddr_t addr, extent_len_t len) {
+      Transaction& t, laddr_t addr) {
     auto iter = allocate_map.find(addr);
     assert(iter != allocate_map.end());
     auto extent = iter->second;
     TRACET("read {}B at {:#x}", t, extent->get_length(), extent->get_laddr());
     assert(extent->get_laddr() == addr);
-    assert(extent->get_length() == len);
     return read_ertr::make_ready_future<NodeExtentRef>(extent);
   }
 
index 3ca8e8263257bbeede21dccb6d5b5e68ae37970c..60c6233088a4827b91bcdd8a36b75e6b3c46ad29 100644 (file)
@@ -97,16 +97,16 @@ class SeastoreNodeExtentManager final: public TransactionManagerHandle {
   bool is_read_isolated() const override { return true; }
 
   read_ertr::future<NodeExtentRef> read_extent(
-      Transaction& t, laddr_t addr, extent_len_t len) override {
-    TRACET("reading {}B at {:#x} ...", t, len, addr);
+      Transaction& t, laddr_t addr) override {
+    TRACET("reading at {:#x} ...", t, addr);
     if constexpr (INJECT_EAGAIN) {
       if (trigger_eagain()) {
-        DEBUGT("reading {}B at {:#x}: trigger eagain", t, len, addr);
+        DEBUGT("reading at {:#x}: trigger eagain", t, addr);
         return crimson::ct_error::eagain::make();
       }
     }
-    return tm.read_extent<SeastoreNodeExtent>(t, addr, len
-    ).safe_then([addr, len, &t](auto&& e) {
+    return tm.read_extent<SeastoreNodeExtent>(t, addr
+    ).safe_then([addr, &t](auto&& e) {
       TRACET("read {}B at {:#x} -- {}",
              t, e->get_length(), e->get_laddr(), *e);
       if (!e->is_valid()) {
@@ -114,9 +114,7 @@ class SeastoreNodeExtentManager final: public TransactionManagerHandle {
         ceph_abort("fatal error");
       }
       assert(e->get_laddr() == addr);
-      assert(e->get_length() == len);
       std::ignore = addr;
-      std::ignore = len;
       return NodeExtentRef(e);
     });
   }
index ebd265d752da5f52f4cc066d5e4cbe8f0fd0385a..ca54eb347642c70c2333313123e907bc8017c9f5 100644 (file)
@@ -69,16 +69,19 @@ class NodeLayoutT final : public InternalNodeImpl, public LeafNodeImpl {
   static eagain_future<typename parent_t::fresh_impl_t> allocate(
       context_t c, bool is_level_tail, level_t level) {
     LOG_PREFIX(OTree::Layout::allocate);
-    // NOTE: Currently, all the node types have the same size for simplicity.
-    // But depending on the requirement, we may need to make node size
-    // configurable by field_type_t and node_type_t, or totally flexible.
-    return c.nm.alloc_extent(c.t, node_stage_t::EXTENT_SIZE
+    extent_len_t extent_size;
+    if constexpr (NODE_TYPE == node_type_t::LEAF) {
+      extent_size = c.vb.get_leaf_node_size();
+    } else {
+      extent_size = c.vb.get_internal_node_size();
+    }
+    return c.nm.alloc_extent(c.t, extent_size
     ).handle_error(
       eagain_ertr::pass_further{},
       crimson::ct_error::input_output_error::handle(
-          [FNAME, c, is_level_tail, level] {
-        ERRORT("EIO -- node_size={}, is_level_tail={}, level={}",
-               c.t, node_stage_t::EXTENT_SIZE, is_level_tail, level);
+          [FNAME, c, extent_size, is_level_tail, level] {
+        ERRORT("EIO -- extent_size={}, is_level_tail={}, level={}",
+               c.t, extent_size, is_level_tail, level);
         ceph_abort("fatal error");
       })
     ).safe_then([is_level_tail, level](auto extent) {
index a61436a5213500fdb64102b62fc69f7b208a482d..3d9538d55aa9d467d5d3a08b91feccefab53139d 100644 (file)
@@ -111,6 +111,10 @@ void validate_tree_config(const tree_conf_t& conf)
               string_key_view_t::VALID_UPPER_BOUND);
   ceph_assert(conf.max_oid_size <
               string_key_view_t::VALID_UPPER_BOUND);
+  ceph_assert(conf.internal_node_size <= MAX_NODE_SIZE);
+  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);
 }
 
 }
index 1833d4b2b2dc830833fd726560b5006375a54d92..f91468d0432cfe3bf988329bd10cce2494be4e8a 100644 (file)
@@ -160,6 +160,8 @@ struct tree_conf_t {
   string_size_t max_ns_size;
   string_size_t max_oid_size;
   value_size_t max_value_payload_size;
+  extent_len_t internal_node_size;
+  extent_len_t leaf_node_size;
 };
 
 class tree_cursor_t;
@@ -258,6 +260,8 @@ struct ValueBuilder {
   virtual string_size_t get_max_ns_size() const = 0;
   virtual string_size_t get_max_oid_size() const = 0;
   virtual value_size_t get_max_value_payload_size() const = 0;
+  virtual extent_len_t get_internal_node_size() const = 0;
+  virtual extent_len_t get_leaf_node_size() const = 0;
   virtual std::unique_ptr<ValueDeltaRecorder>
   build_value_recorder(ceph::bufferlist&) const = 0;
 };
@@ -285,6 +289,12 @@ struct ValueBuilderImpl final : public ValueBuilder {
   value_size_t get_max_value_payload_size() const override {
     return ValueImpl::TREE_CONF.max_value_payload_size;
   }
+  extent_len_t get_internal_node_size() const override {
+    return ValueImpl::TREE_CONF.internal_node_size;
+  }
+  extent_len_t get_leaf_node_size() const override {
+    return ValueImpl::TREE_CONF.leaf_node_size;
+  }
 
   std::unique_ptr<ValueDeltaRecorder>
   build_value_recorder(ceph::bufferlist& encoded) const override {
index fec4c54c8518711d17e3d5eeb9aa9180d5f4a725..cb5093638370212a2c0b2bcc368ad67c684e0377 100644 (file)
@@ -39,14 +39,18 @@ inline std::ostream& operator<<(std::ostream& os, const test_item_t& item) {
 template <value_magic_t MAGIC,
           string_size_t MAX_NS_SIZE,
           string_size_t MAX_OID_SIZE,
-          value_size_t  MAX_VALUE_PAYLOAD_SIZE>
+          value_size_t  MAX_VALUE_PAYLOAD_SIZE,
+          extent_len_t  INTERNAL_NODE_SIZE,
+          extent_len_t  LEAF_NODE_SIZE>
 class TestValue final : public Value {
  public:
   static constexpr tree_conf_t TREE_CONF = {
     MAGIC,
     MAX_NS_SIZE,
     MAX_OID_SIZE,
-    MAX_VALUE_PAYLOAD_SIZE
+    MAX_VALUE_PAYLOAD_SIZE,
+    INTERNAL_NODE_SIZE,
+    LEAF_NODE_SIZE
   };
 
   using id_t = test_item_t::id_t;
@@ -197,8 +201,8 @@ class TestValue final : public Value {
 };
 
 using UnboundedValue = TestValue<
-  value_magic_t::TEST_UNBOUND, 4096, 4096, 4096>;
+  value_magic_t::TEST_UNBOUND, 4096, 4096, 4096, 4096, 4096>;
 using BoundedValue   = TestValue<
-  value_magic_t::TEST_BOUNDED,  320,  320,  640>;
+  value_magic_t::TEST_BOUNDED,  320,  320,  640, 4096, 4096>;
 
 }