crimson/onode-staged-tree: implement size upper-bounds to value
authorYingxin Cheng <yingxin.cheng@intel.com>
Wed, 2 Jun 2021 05:18:48 +0000 (13:18 +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/tree.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 a1f73e4a711685ebfe82c0b664514d98c2ca4f6e..d075364af19933f63eb8d3ca5af128d442db1627 100644 (file)
@@ -13,7 +13,8 @@ struct FLTreeOnode final : Onode, Value {
   static constexpr tree_conf_t TREE_CONF = {
     value_magic_t::ONODE,
     128,        // max_ns_size
-    320         // max_oid_size
+    320,        // max_oid_size
+    1200        // max_value_payload_size
   };
 
   enum class status_t {
index 7fa41b03df6b6ab4ebb192b48c71813a890f3f42..c1568461d4b43b333867202e87b3d7913fee8eb0 100644 (file)
@@ -246,6 +246,12 @@ class Btree {
     crimson::ct_error::value_too_large>;
   insert_ertr::future<std::pair<Cursor, bool>>
   insert(Transaction& t, const ghobject_t& obj, tree_value_config_t _vconf) {
+    LOG_PREFIX(OTree::insert);
+    if (_vconf.payload_size > value_builder.get_max_value_payload_size()) {
+      ERRORT("value payload size {} too large to insert {}",
+             t, _vconf.payload_size, key_hobj_t{obj});
+      return crimson::ct_error::value_too_large::make();
+    }
     if (obj.hobj.nspace.size() > value_builder.get_max_ns_size()) {
       ERRORT("namespace size {} too large to insert {}",
              t, obj.hobj.nspace.size(), key_hobj_t{obj});
index 03e3f8792b3cfe699a376afd445ba5289d6b4748..a61436a5213500fdb64102b62fc69f7b208a482d 100644 (file)
@@ -71,7 +71,9 @@ eagain_future<> Value::trim(Transaction& t, value_size_t trim_size)
 
 const value_header_t* Value::read_value_header() const
 {
-  return p_cursor->read_value_header(vb.get_header_magic());
+  auto ret = p_cursor->read_value_header(vb.get_header_magic());
+  assert(ret->payload_size <= vb.get_max_value_payload_size());
+  return ret;
 }
 
 std::pair<NodeExtentMutable&, ValueDeltaRecorder*>
index 2a0ef8a43e8701b6e306c4fbbc977730da5321f8..1833d4b2b2dc830833fd726560b5006375a54d92 100644 (file)
@@ -159,6 +159,7 @@ struct tree_conf_t {
   value_magic_t value_magic;
   string_size_t max_ns_size;
   string_size_t max_oid_size;
+  value_size_t max_value_payload_size;
 };
 
 class tree_cursor_t;
@@ -256,6 +257,7 @@ struct ValueBuilder {
   virtual value_magic_t get_header_magic() const = 0;
   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 std::unique_ptr<ValueDeltaRecorder>
   build_value_recorder(ceph::bufferlist&) const = 0;
 };
@@ -280,6 +282,9 @@ struct ValueBuilderImpl final : public ValueBuilder {
   string_size_t get_max_oid_size() const override {
     return ValueImpl::TREE_CONF.max_oid_size;
   }
+  value_size_t get_max_value_payload_size() const override {
+    return ValueImpl::TREE_CONF.max_value_payload_size;
+  }
 
   std::unique_ptr<ValueDeltaRecorder>
   build_value_recorder(ceph::bufferlist& encoded) const override {
index 6501047e67162c38c17255bc5d0408dfcdbff275..fec4c54c8518711d17e3d5eeb9aa9180d5f4a725 100644 (file)
@@ -38,13 +38,15 @@ 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>
+          string_size_t MAX_OID_SIZE,
+          value_size_t  MAX_VALUE_PAYLOAD_SIZE>
 class TestValue final : public Value {
  public:
   static constexpr tree_conf_t TREE_CONF = {
     MAGIC,
     MAX_NS_SIZE,
-    MAX_OID_SIZE
+    MAX_OID_SIZE,
+    MAX_VALUE_PAYLOAD_SIZE
   };
 
   using id_t = test_item_t::id_t;
@@ -195,8 +197,8 @@ class TestValue final : public Value {
 };
 
 using UnboundedValue = TestValue<
-  value_magic_t::TEST_UNBOUND, 4096, 4096>;
+  value_magic_t::TEST_UNBOUND, 4096, 4096, 4096>;
 using BoundedValue   = TestValue<
-  value_magic_t::TEST_BOUNDED,  320,  320>;
+  value_magic_t::TEST_BOUNDED,  320,  320,  640>;
 
 }