]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
crimson/os/seastore/lba_mapping: add interfaces to determine the pending
authorXuehan Xu <xuxuehan@qianxin.com>
Thu, 3 Jul 2025 08:36:27 +0000 (16:36 +0800)
committerXuehan Xu <xuxuehan@qianxin.com>
Tue, 5 Aug 2025 06:33:59 +0000 (14:33 +0800)
state of mappings' child extents

Signed-off-by: Xuehan Xu <xuxuehan@qianxin.com>
src/crimson/os/seastore/cache.h
src/crimson/os/seastore/lba/lba_btree_node.h
src/crimson/os/seastore/lba_mapping.cc
src/crimson/os/seastore/lba_mapping.h
src/crimson/os/seastore/linked_tree_node.h

index 0ae19c34317e3781515b9611618cdb53bd4bfe63..332a5ebecbab257ed96fd35a4b37c340b2e25e49 100644 (file)
@@ -449,22 +449,12 @@ public:
       std::forward<Func>(extent_init_func));
   }
 
-  bool is_viewable_extent_stable(
+  CachedExtentRef peek_extent_viewable_by_trans(
     Transaction &t,
     CachedExtentRef extent) final
   {
     assert(extent);
-    auto view = extent->get_transactional_view(t);
-    return view->is_stable();
-  }
-
-  bool is_viewable_extent_data_stable(
-    Transaction &t,
-    CachedExtentRef extent) final
-  {
-    assert(extent);
-    auto view = extent->get_transactional_view(t);
-    return view->is_data_stable();
+    return extent->get_transactional_view(t);
   }
 
   get_extent_iertr::future<> maybe_wait_accessible(
index 05f26b6b29273873fe1f4fa439a89c28ba5a8ada..94b73c342cd635604b2e9c45f9d965eafd42ff39 100644 (file)
@@ -217,13 +217,20 @@ struct LBALeafNode
     op_context_t c,
     uint16_t pos,
     laddr_t key) const {
-    return parent_node_t::_is_child_stable(c.trans, c.cache, pos, key);
+    return parent_node_t::is_child_stable(c.trans, c.cache, pos, key);
   }
   bool is_child_data_stable(
     op_context_t c,
     uint16_t pos,
     laddr_t key) const {
-    return parent_node_t::_is_child_stable(c.trans, c.cache, pos, key, true);
+    return parent_node_t::is_child_stable(c.trans, c.cache, pos, key, true);
+  }
+  bool is_child_initial_pending(
+    op_context_t c,
+    uint16_t pos,
+    laddr_t key) const {
+    return parent_node_t::is_child_initial_pending(
+      c.trans, c.cache, pos, key);
   }
 
   void on_split(
index a4bbf4a41ff52069b66d8ca011ccad214daf09d9..53b52b39e9249445f5ad49435706e24553c2b9c9 100644 (file)
@@ -129,4 +129,15 @@ LBAMapping::refresh_iertr::future<LBAMapping> LBAMapping::refresh()
   });
 }
 
+bool LBAMapping::is_initial_pending() const {
+  assert(is_linked_direct());
+  ceph_assert(direct_cursor->is_viewable());
+  assert(!direct_cursor->is_end());
+  auto leaf = direct_cursor->parent->cast<LBALeafNode>();
+  return leaf->is_child_initial_pending(
+    direct_cursor->ctx,
+    direct_cursor->pos,
+    direct_cursor->key);
+}
+
 } // namespace crimson::os::seastore
index cefb288713fd7f16d93896376d45b019e8fc71d2..2fc06fac0693602a65a1fcf1e218de73ddf744b3 100644 (file)
@@ -51,6 +51,9 @@ public:
     return !is_indirect() && !is_data_stable();
   }
 
+  // whether the mapping corresponds to an initial pending extent
+  bool is_initial_pending() const;
+
   bool is_linked_direct() const {
     return (bool)direct_cursor;
   }
@@ -155,7 +158,13 @@ public:
   get_child_ret_t<lba::LBALeafNode, LogicalChildNode>
   get_logical_extent(Transaction &t) const;
 
+  LogicalChildNodeRef peek_logical_extent(Transaction &t) const;
+
   using refresh_iertr = LBACursor::base_iertr;
+  //TODO: should be changed to return future<> once all calls
+  //     to refresh are through co_await. We return LBAMapping
+  //     for now to avoid mandating the callers to make sure
+  //     the life of the lba mapping survives the refresh.
   refresh_iertr::future<LBAMapping> refresh();
 
   using next_iertr = LBACursor::base_iertr;
index 2dd152b07e766b356b34e6429ad2e29710c5ed6c..40f9aa513af4247df6421d91d656f4cd63717bd2 100644 (file)
@@ -251,8 +251,8 @@ public:
   }
   virtual get_child_iertr::future<> maybe_wait_accessible(
     Transaction &, CachedExtent&) = 0;
-  virtual bool is_viewable_extent_data_stable(Transaction &, CachedExtentRef) = 0;
-  virtual bool is_viewable_extent_stable(Transaction &, CachedExtentRef) = 0;
+  virtual CachedExtentRef peek_extent_viewable_by_trans(
+    Transaction &t, CachedExtentRef extent) = 0;
   virtual ~ExtentTransViewRetriever() {}
 protected:
   virtual get_child_iertr::future<CachedExtentRef> get_extent_viewable_by_trans(
@@ -884,54 +884,68 @@ protected:
     assert(me.validate_stable_children());
   }
 
-  // children are considered stable if any of the following case is true:
-  // 1. The child extent is absent in cache
-  // 2. The child extent is (data) stable
-  //
-  // For reserved mappings, the return values are undefined.
-  bool _is_child_stable(
+  CachedExtentRef peek_child(
     Transaction &t,
     ExtentTransViewRetriever &etvr,
     btreenode_pos_t pos,
-    node_key_t key,
-    bool data_only = false) const {
+    node_key_t key) const
+  {
     auto &me = down_cast();
-    assert(key == me.iter_idx(pos).get_key());
-    auto child = this->children[pos];
+    assert(children.capacity());
+    assert(key == down_cast().iter_idx(pos).get_key());
+    auto child = children[pos];
     if (is_reserved_ptr(child)) {
-      return true;
+      return nullptr;
     } else if (is_valid_child_ptr(child)) {
-      assert(dynamic_cast<CachedExtent*>(child)->is_logical());
-      assert(
-       dynamic_cast<CachedExtent*>(child)->is_pending_in_trans(t.get_trans_id())
-       || me.is_stable_ready());
-      if (data_only) {
-       return etvr.is_viewable_extent_data_stable(
-         t, dynamic_cast<CachedExtent*>(child));
-      } else {
-       return etvr.is_viewable_extent_stable(
-         t, dynamic_cast<CachedExtent*>(child));
-      }
+      return etvr.peek_extent_viewable_by_trans(
+       t, dynamic_cast<CachedExtent*>(child));
     } else if (me.is_pending()) {
-      auto key = me.iter_idx(pos).get_key();
       auto &sparent = me.get_stable_for_key(key);
       auto spos = sparent.lower_bound(key).get_offset();
       auto child = sparent.children[spos];
       if (is_valid_child_ptr(child)) {
-       assert(dynamic_cast<CachedExtent*>(child)->is_logical());
-       if (data_only) {
-         return etvr.is_viewable_extent_data_stable(
-           t, dynamic_cast<CachedExtent*>(child));
-       } else {
-         return etvr.is_viewable_extent_stable(
-           t, dynamic_cast<CachedExtent*>(child));
-       }
+       return etvr.peek_extent_viewable_by_trans(
+         t, dynamic_cast<CachedExtent*>(child));
       } else {
-       return true;
+       return nullptr;
       }
     } else {
+      return nullptr;
+    }
+  }
+
+  // children are considered stable if any of the following case is true:
+  // 1. The child extent is absent in cache
+  // 2. The child extent is (data) stable
+  //
+  // For reserved mappings, the return values are undefined.
+  bool is_child_stable(
+    Transaction &t,
+    ExtentTransViewRetriever &etvr,
+    btreenode_pos_t pos,
+    node_key_t key,
+    bool data_only = false) const {
+    auto extent = peek_child(t, etvr, pos, key);
+    if (!extent) {
       return true;
     }
+    if (data_only) {
+      return extent->is_data_stable();
+    } else {
+      return extent->is_stable();
+    }
+  }
+
+  bool is_child_initial_pending(
+    Transaction &t,
+    ExtentTransViewRetriever &etvr,
+    btreenode_pos_t pos,
+    node_key_t key) const {
+    auto extent = peek_child(t, etvr, pos, key);
+    if (!extent) {
+      return false;
+    }
+    return extent->is_initial_pending();
   }
 
   parent_tracker_t<T>* my_tracker = nullptr;