]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
crimson/onode-staged-tree: reset root node after lookup
authorYingxin Cheng <yingxin.cheng@intel.com>
Thu, 24 Jun 2021 07:50:18 +0000 (15:50 +0800)
committerYingxin Cheng <yingxin.cheng@intel.com>
Fri, 25 Jun 2021 02:40:28 +0000 (10:40 +0800)
Otherwise there could be unexpected references that will break the
asserts when remove nodes during insert/delete.

Signed-off-by: Yingxin Cheng <yingxin.cheng@intel.com>
src/crimson/os/seastore/onode_manager/staged-fltree/node.cc
src/crimson/os/seastore/onode_manager/staged-fltree/node.h
src/crimson/os/seastore/onode_manager/staged-fltree/tree.h

index 6d75d58dfff17454fef90751e9dc81b019efed7f..16cb1b7e214e84ad28b2c422d376739899c7adc0 100644 (file)
@@ -311,12 +311,19 @@ eagain_future<Node::search_result_t> Node::lower_bound(
 }
 
 eagain_future<std::pair<Ref<tree_cursor_t>, bool>> Node::insert(
-    context_t c, const key_hobj_t& key, value_config_t vconf)
+    context_t c,
+    const key_hobj_t& key,
+    value_config_t vconf,
+    Ref<Node>&& this_ref)
 {
   return seastar::do_with(
-    MatchHistory(), [this, c, &key, vconf](auto& history) {
+    MatchHistory(), [this, c, &key, vconf,
+                     this_ref = std::move(this_ref)] (auto& history) mutable {
       return lower_bound_tracked(c, key, history
-      ).safe_then([c, &key, vconf, &history](auto result) {
+      ).safe_then([c, &key, vconf, &history,
+                   this_ref = std::move(this_ref)] (auto result) mutable {
+        // the cursor in the result should already hold the root node upwards
+        this_ref.reset();
         if (result.match() == MatchKindBS::EQ) {
           return eagain_ertr::make_ready_future<std::pair<Ref<tree_cursor_t>, bool>>(
               std::make_pair(result.p_cursor, false));
@@ -335,9 +342,14 @@ eagain_future<std::pair<Ref<tree_cursor_t>, bool>> Node::insert(
 }
 
 eagain_future<std::size_t> Node::erase(
-    context_t c, const key_hobj_t& key)
+    context_t c,
+    const key_hobj_t& key,
+    Ref<Node>&& this_ref)
 {
-  return lower_bound(c, key).safe_then([c] (auto result) {
+  return lower_bound(c, key
+  ).safe_then([c, this_ref = std::move(this_ref)] (auto result) mutable {
+    // the cursor in the result should already hold the root node upwards
+    this_ref.reset();
     if (result.match() != MatchKindBS::EQ) {
       return eagain_ertr::make_ready_future<std::size_t>(0);
     }
index bfa27cf2560fcf649dc506b31f9ad4d4014cea54..6434c3fc90b8ff50a3507b888e1d42d1e4662ba9 100644 (file)
@@ -336,7 +336,7 @@ class Node
    * - If false, the returned cursor points to the conflicting element in tree;
    */
   eagain_future<std::pair<Ref<tree_cursor_t>, bool>> insert(
-      context_t, const key_hobj_t&, value_config_t);
+      context_t, const key_hobj_t&, value_config_t, Ref<Node>&&);
 
   /**
    * erase
@@ -345,7 +345,7 @@ class Node
    *
    * Returns the number of erased key-value pairs (0 or 1).
    */
-  eagain_future<std::size_t> erase(context_t, const key_hobj_t&);
+  eagain_future<std::size_t> erase(context_t, const key_hobj_t&, Ref<Node>&&);
 
   /// Recursively collects the statistics of the sub-tree formed by this node
   eagain_future<tree_stats_t> get_tree_stats(context_t);
index c1568461d4b43b333867202e87b3d7913fee8eb0..b75425935cd7a4352625f9f97d0882f05d0e1ee9 100644 (file)
@@ -268,7 +268,7 @@ class Btree {
       [this, &t, vconf](auto& key) -> eagain_future<std::pair<Cursor, bool>> {
         ceph_assert(key.is_valid());
         return get_root(t).safe_then([this, &t, &key, vconf](auto root) {
-          return root->insert(get_context(t), key, vconf);
+          return root->insert(get_context(t), key, vconf, std::move(root));
         }).safe_then([this](auto ret) {
           auto& [cursor, success] = ret;
           return std::make_pair(Cursor(this, cursor), success);
@@ -282,7 +282,7 @@ class Btree {
       full_key_t<KeyT::HOBJ>(obj),
       [this, &t](auto& key) -> eagain_future<std::size_t> {
         return get_root(t).safe_then([this, &t, &key](auto root) {
-          return root->erase(get_context(t), key);
+          return root->erase(get_context(t), key, std::move(root));
         });
       }
     );