From: Zhang Song Date: Wed, 11 Jun 2025 03:50:12 +0000 (+0800) Subject: crimson/os/seastore/Onode: get sibling's object id when creating new onode X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=3222f3ef5572ebe607028e142fb0974046512bf8;p=ceph-ci.git crimson/os/seastore/Onode: get sibling's object id when creating new onode Signed-off-by: Zhang Song --- diff --git a/src/crimson/os/seastore/onode.h b/src/crimson/os/seastore/onode.h index 8929bd45ab7..5c72f84d21b 100644 --- a/src/crimson/os/seastore/onode.h +++ b/src/crimson/os/seastore/onode.h @@ -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); }; diff --git a/src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.cc b/src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.cc index a4f3b59e975..8a1c163dcf0 100644 --- a/src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.cc +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.cc @@ -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( 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(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