]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
crimson/os/seastore/Onode: get sibling's object id when creating new onode
authorZhang Song <zhangsong02@qianxin.com>
Wed, 11 Jun 2025 03:50:12 +0000 (11:50 +0800)
committerXuehan Xu <xuxuehan@qianxin.com>
Mon, 2 Feb 2026 11:37:02 +0000 (19:37 +0800)
Signed-off-by: Zhang Song <zhangsong02@qianxin.com>
src/crimson/os/seastore/onode.h
src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.cc

index 8929bd45ab748f7d1014d006bb5422bbcbb89284..5c72f84d21b5d71957f2532ec130daf5854d9543 100644 (file)
@@ -205,6 +205,10 @@ public:
     }
     return std::nullopt;
   }
+  void set_sibling_object_id(local_object_id_t id) {
+    assert(!sibling_object_id);
+    sibling_object_id = id;
+  }
   friend std::ostream& operator<<(std::ostream &out, const Onode &rhs);
 };
 
index a4f3b59e9758a7bc330dad441baac39cf9ded50a..8a1c163dcf093e36759e1f1f42d4c2f804ca4e29 100644 (file)
@@ -183,31 +183,84 @@ FLTreeOnodeManager::get_onode_ret FLTreeOnodeManager::get_onode(
       return crimson::ct_error::enoent::make();
     }
     auto val = OnodeRef(new FLTreeOnode(hoid.hobj, cursor.value()));
+    assert(val->get_clone_prefix());
     return get_onode_iertr::make_ready_future<OnodeRef>(
       val
     );
   });
 }
 
+namespace {
+struct ghobj_cmp_t {
+  bool same_object;
+  bool equal;
+};
+ghobj_cmp_t compare_ghobj(ghobject_t &identity, const ghobject_t &base) {
+  auto snap_bak = identity.hobj.snap;
+  identity.hobj.snap = base.hobj.snap;
+  bool same_object = (identity == base);
+  bool equal = same_object && (snap_bak == base.hobj.snap);
+  identity.hobj.snap = snap_bak;
+  return {same_object, equal};
+}
+}
+
 FLTreeOnodeManager::get_or_create_onode_ret
 FLTreeOnodeManager::get_or_create_onode(
   Transaction &trans,
   const ghobject_t &hoid)
 {
   LOG_PREFIX(FLTreeOnodeManager::get_or_create_onode);
-  return tree.insert(
+  auto [cursor, created] = co_await tree.insert(
     trans, hoid,
-    OnodeTree::tree_value_config_t{sizeof(onode_layout_t)}
-  ).si_then([&trans, &hoid, FNAME](auto p)
-              -> get_or_create_onode_ret {
-    auto [cursor, created] = std::move(p);
-    auto onode = new FLTreeOnode(hoid.hobj, cursor.value());
-    if (created) {
-      DEBUGT("created onode for entry for {}", trans, hoid);
-      onode->create_default_layout(trans);
-    }
-    return get_or_create_onode_iertr::make_ready_future<OnodeRef>(onode);
-  });
+    OnodeTree::tree_value_config_t{sizeof(onode_layout_t)});
+
+  auto flonode = new FLTreeOnode(hoid.hobj, cursor.value());
+  if (!created) {
+    DEBUGT("onode exists for {}", trans, hoid);
+    assert(flonode->get_clone_prefix());
+    co_return flonode;
+  }
+  assert(!cursor.is_end());
+  // new onode created
+  DEBUGT("created onode for entry for {}", trans, hoid);
+  flonode->create_default_layout(trans);
+
+  // handle object id from sibling
+  auto onode = OnodeRef(flonode);
+  if (!hoid.hobj.is_head()) {
+    // cur onode is not head, move to next onode to check if it's
+    // the clone sibling under the same object.
+    auto next_cursor = co_await tree.get_next(trans, cursor);
+    if (!next_cursor.is_end()) {
+      auto nxt_oid = next_cursor.get_ghobj();
+      auto ret = compare_ghobj(nxt_oid, hoid);
+      assert(!ret.equal);
+      if (ret.same_object) {
+        auto nxt_onode = next_cursor.value();
+        auto prefix = nxt_onode.get_clone_prefix();
+        auto object_id = prefix->get_local_object_id();
+        onode->set_sibling_object_id(object_id);
+        co_return onode;
+      } // not same object, fallthrough to search prev onode
+    } // is end, fallthrough to search prev onode
+  } // is head, fallthrough to search prev onode
+
+  auto hint = hoid;
+  hint.hobj.snap = 0;
+  auto prev_cursor = co_await tree.lower_bound(trans, hint);
+
+  assert(!prev_cursor.is_end());
+  auto prv_oid = prev_cursor.get_ghobj();
+  auto ret = compare_ghobj(prv_oid, hoid);
+  if (!ret.equal && ret.same_object) {
+    // sibling clone onode exists
+    auto prv_onode = prev_cursor.value();
+    auto prefix = prv_onode.get_clone_prefix();
+    auto object_id = prefix->get_local_object_id();
+    onode->set_sibling_object_id(object_id);
+  } // else sibling clone onode not found, hoid is the first clone
+  co_return onode;
 }
 
 FLTreeOnodeManager::get_or_create_onodes_ret