]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore/cache: re-implement Cache::retire_absent_extent_addr
authorXuehan Xu <xuxuehan@qianxin.com>
Wed, 20 May 2026 08:31:29 +0000 (16:31 +0800)
committerXuehan Xu <xuxuehan@qianxin.com>
Fri, 22 May 2026 05:53:26 +0000 (13:53 +0800)
The new implementation retire an absent extent by constructing a real
empty extent and add it to the transaction's retired_set, instead of
creating a retired placeholder

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

index e1682f835cdd0415362a0ca1c187de8dd6719aaf..d8041d01d9b5d55a135201e6b0e4e2ed26a64c2e 100644 (file)
@@ -95,31 +95,50 @@ Cache::retire_extent_ret Cache::retire_extent_addr(
   return retire_extent_iertr::now();
 }
 
-CachedExtentRef Cache::retire_absent_extent_addr(
-  Transaction &t, laddr_t laddr, paddr_t paddr, extent_len_t length)
+CachedExtentRef Cache::retire_absent_extent_addr_by_type(
+  Transaction &t,
+  laddr_t laddr,
+  paddr_t addr,
+  extent_len_t length,
+  extent_types_t type,
+  extent_init_func_t &&extent_init_func)
 {
-  assert(paddr.is_absolute());
-
-  CachedExtentRef ext;
-#ifndef NDEBUG
-  auto result = t.get_extent(paddr, &ext);
-  assert(result != Transaction::get_extent_ret::PRESENT
-    && result != Transaction::get_extent_ret::RETIRED);
-  assert(!query_cache(paddr));
-#endif
-  LOG_PREFIX(Cache::retire_absent_extent_addr);
-  // add a new placeholder to Cache
-  ext = CachedExtent::make_cached_extent_ref<
-    RetiredExtentPlaceholder>(length);
-  ext->init(
-    CachedExtent::extent_state_t::CLEAN, paddr,
-    PLACEMENT_HINT_NULL, NULL_GENERATION, TRANS_ID_NULL);
-  static_cast<RetiredExtentPlaceholder&>(*ext).set_laddr(laddr);
-  DEBUGT("retire {}~0x{:x} as placeholder, add extent -- {}",
-        t, paddr, length, *ext);
-  add_extent(ext);
-  t.add_absent_to_retired_set(ext);
-  return ext;
+  switch (type) {
+  case extent_types_t::ROOT_META:
+    return retire_absent_extent_addr<RootMetaBlock>(
+      t, laddr, addr, length, std::move(extent_init_func));
+  case extent_types_t::ONODE_BLOCK_STAGED:
+    return retire_absent_extent_addr<onode::SeastoreNodeExtent>(
+      t, laddr, addr, length, std::move(extent_init_func));
+  case extent_types_t::OMAP_INNER:
+    return retire_absent_extent_addr<omap_manager::OMapInnerNode>(
+      t, laddr, addr, length, std::move(extent_init_func));
+  case extent_types_t::OMAP_LEAF:
+    return retire_absent_extent_addr<omap_manager::OMapLeafNode>(
+      t, laddr, addr, length, std::move(extent_init_func));
+  case extent_types_t::COLL_BLOCK:
+    return retire_absent_extent_addr<collection_manager::CollectionNode>(
+      t, laddr, addr, length, std::move(extent_init_func));
+  case extent_types_t::TEST_BLOCK_PHYSICAL:
+    return retire_absent_extent_addr<TestBlockPhysical>(
+      t, laddr, addr, length, std::move(extent_init_func));
+  case extent_types_t::LOG_NODE:
+    return retire_absent_extent_addr<log_manager::LogNode>(
+      t, laddr, addr, length, std::move(extent_init_func));
+  case extent_types_t::OBJECT_DATA_BLOCK:
+    return retire_absent_extent_addr<ObjectDataBlock>(
+      t, laddr, addr, length, std::move(extent_init_func));
+  case extent_types_t::TEST_BLOCK:
+    return retire_absent_extent_addr<TestBlock>(
+      t, laddr, addr, length, std::move(extent_init_func));
+  case extent_types_t::NONE: {
+    ceph_assert(0 == "NONE is an invalid extent type");
+    return CachedExtentRef();
+  }
+  default:
+    ceph_assert(0 == "impossible");
+    return CachedExtentRef();
+  }
 }
 
 void Cache::dump_contents()
index 3a9883ccdf81065041b0e0205954d3a92653c480..b900b3b6cb9db8a509f8324bb6ab4a897f20b2c9 100644 (file)
@@ -160,8 +160,22 @@ public:
   retire_extent_ret retire_extent_addr(
     Transaction &t, paddr_t addr, extent_len_t length);
 
-  CachedExtentRef retire_absent_extent_addr(
-    Transaction &t, laddr_t laddr, paddr_t addr, extent_len_t length);
+  template <typename T, typename Func>
+  TCachedExtentRef<T> retire_absent_extent_addr(
+    Transaction &t,
+    laddr_t laddr,
+    paddr_t paddr,
+    extent_len_t length,
+    Func &&extent_init_func) {
+    LOG_PREFIX(Cache::retire_absent_extent_addr);
+    SUBDEBUGT(seastore_cache, "retire {}~0x{:x} laddr={}",
+      t, paddr, length, laddr);
+    auto ext = alloc_absent_extent<T>(
+      t, paddr, length, 0, length, std::move(extent_init_func));
+    SUBDEBUGT(seastore_cache, "retire {}", t, *ext);
+    retire_extent(t, ext);
+    return ext;
+  }
 
   /**
    * get_root
@@ -392,41 +406,19 @@ public:
     extent_len_t partial_off,
     extent_len_t partial_len,
     Func &&extent_init_func) {
-    LOG_PREFIX(Cached::prepare_absent_extent);
-
-#ifndef NDEBUG
-    {
-      CachedExtentRef ret;
-      auto r = t.get_extent(offset, &ret);
-      if (r != Transaction::get_extent_ret::ABSENT) {
-       SUBERRORT(seastore_cache, "unexpected non-absent extent {}", t, *ret);
-       ceph_abort();
-      }
-    }
-#endif
-
-    SUBTRACET(seastore_cache, "{} {}~0x{:x}", t, T::TYPE, offset, length);
-    ceph_assert(!booting);
+    auto ret = alloc_absent_extent<T>(
+      t,
+      offset,
+      length,
+      partial_off,
+      partial_len,
+      std::forward<Func>(extent_init_func));
     const auto t_src = t.get_src();
-
-    // partial read
-    TCachedExtentRef<T> ret = CachedExtent::make_cached_extent_ref<T>(length);
-    ret->init(CachedExtent::extent_state_t::CLEAN,
-             offset,
-             PLACEMENT_HINT_NULL,
-             NULL_GENERATION,
-             TRANS_ID_NULL);
-    SUBDEBUGT(seastore_cache,
-       "{} {}~0x{:x} is absent, add extent and reading range 0x{:x}~0x{:x} ... -- {}",
-       t, T::TYPE, offset, length, partial_off, partial_len, *ret);
-    add_extent(ret);
-    extent_init_func(*ret);
     cache_access_stats_t& access_stats = get_by_ext(
       get_by_src(stats.access_by_src_ext, t_src),
       T::TYPE);
     ++access_stats.load_absent;
     ++stats.access.load_absent;
-    t.add_to_read_set(CachedExtentRef(ret));
     touch_extent_by_range(
       *ret, &t_src, t.get_cache_hint(),
       partial_off, partial_len);
@@ -832,6 +824,47 @@ private:
     }
   }
 
+  /**
+   */
+  template <typename T, typename Func>
+  TCachedExtentRef<T> alloc_absent_extent(
+    Transaction &t,
+    paddr_t offset,
+    extent_len_t length,
+    extent_len_t partial_off,
+    extent_len_t partial_len,
+    Func &&extent_init_func) {
+    LOG_PREFIX(Cache::alloc_absent_extent);
+#ifndef NDEBUG
+    {
+      CachedExtentRef ret;
+      auto r = t.get_extent(offset, &ret);
+      if (r != Transaction::get_extent_ret::ABSENT) {
+       SUBERRORT(seastore_cache, "unexpected non-absent extent {}", t, *ret);
+       ceph_abort();
+      }
+    }
+#endif
+
+    SUBTRACET(seastore_cache, "{} {}~0x{:x}", t, T::TYPE, offset, length);
+    ceph_assert(!booting);
+
+    // partial read
+    TCachedExtentRef<T> ret = CachedExtent::make_cached_extent_ref<T>(length);
+    ret->init(CachedExtent::extent_state_t::CLEAN,
+             offset,
+             PLACEMENT_HINT_NULL,
+             NULL_GENERATION,
+             TRANS_ID_NULL);
+    SUBDEBUGT(seastore_cache,
+       "{} {}~0x{:x} is absent, add extent and reading range 0x{:x}~0x{:x} ... -- {}",
+       t, T::TYPE, offset, length, partial_off, partial_len, *ret);
+    add_extent(ret);
+    extent_init_func(*ret);
+    t.add_to_read_set(ret);
+    return ret;
+  }
+
   /**
    * do_get_caching_extent
    *
@@ -1306,6 +1339,19 @@ public:
     rewrite_gen_t gen      ///< [in] rewrite generation
     );
 
+  /**
+   * retire_absent_extent_addr_by_type
+   *
+   * Construct a fresh extent, and add it to the retired_set of the transaction.
+   */
+  CachedExtentRef retire_absent_extent_addr_by_type(
+    Transaction &t,
+    laddr_t laddr,
+    paddr_t addr,
+    extent_len_t length,
+    extent_types_t type,
+    extent_init_func_t &&extent_init_func);
+
   /**
    * Allocates mutable buffer from extent_set on offset~len
    *
index b132257b05bd53f33a23df6a3402c7acc0c2b894..c836b5d3b7f824d9289866d2677fd5645b03ea6f 100644 (file)
@@ -342,7 +342,7 @@ BtreeLBAManager::clone_mapping(
       inter_key,
       EXTENT_DEFAULT_REF_COUNT,
       0,
-      extent_types_t::NONE},
+      mapping->get_extent_type()},
     get_reserved_ptr<LBALeafNode, laddr_t>());
   auto &[iter, inserted] = p;
   co_await mapping->refresh();
index c42be7c1ba8817a0eb3b8d1f1293e44cc07959ba..0a5f56b62cab48c296be9354d99eba3d30e390d7 100644 (file)
@@ -442,6 +442,12 @@ struct LBACursor : BtreeCursor<laddr_t, lba::lba_map_val_t, LBALeafNode> {
     return iter.get_val().refcount;
   }
 
+  extent_types_t get_extent_type() const {
+    assert(is_viewable());
+    assert(!is_end());
+    return iter.get_val().type;
+  }
+
   base_iertr::future<> refresh();
 private:
 
index fbfa10ac8bdda35abd10ca9837be39cd4f7b6772..5ef5f8a62b8cc8e10a9eb554704a71e01e2854ea 100644 (file)
@@ -175,6 +175,21 @@ public:
       extent_len_t>(get_intermediate_key());
   }
 
+  extent_types_t get_extent_type() const {
+    if (direct_cursor && indirect_cursor) {
+      assert(direct_cursor->get_extent_type()
+             == indirect_cursor->get_extent_type());
+    }
+    if (direct_cursor) {
+      return direct_cursor->get_extent_type();
+    } else if (indirect_cursor) {
+      return indirect_cursor->get_extent_type();
+    } else {
+      ceph_abort("invalid LBAMapping");
+      return extent_types_t::NONE;
+    }
+  }
+
   get_child_ret_t<lba::LBALeafNode, LogicalChildNode>
   get_logical_extent(Transaction &t) const;
 
index 147a2c48b7ffa26001ed4dfede5752c3d910a42e..720719139fafcab286991bce806db8e9d11c0cd3 100644 (file)
@@ -297,12 +297,23 @@ TransactionManager::_remove(
       ceph_assert(extent);
       cache->retire_extent(t, std::move(extent));
     } else {
-      auto retired_placeholder = cache->retire_absent_extent_addr(
-       t, mapping.get_intermediate_base(),
+      auto &child_pos = maybe_mapped_extent.get_child_pos();
+      auto laddr = mapping.get_intermediate_base();
+      std::ignore = cache->retire_absent_extent_addr_by_type(
+       t, laddr,
        mapping.get_val(),
-       mapping.get_intermediate_length()
-      )->template cast<RetiredExtentPlaceholder>();
-      maybe_mapped_extent.get_child_pos().link_child(retired_placeholder.get());
+       mapping.get_intermediate_length(),
+        mapping.get_extent_type(),
+        [this, &child_pos, laddr, &t](auto &extent) mutable {
+          auto lextent = extent.template cast<LogicalChildNode>();
+          assert(extent.is_logical());
+          assert(!lextent->has_laddr());
+          assert(!extent.has_been_invalidated());
+          child_pos.link_child(lextent.get());
+          child_pos.invalidate_retired_placeholder(t, *cache, extent);
+          lextent->set_laddr(laddr);
+        }
+      );
     }
   }
 
index 4032c400927dfa7eee032420c9bf91cd3630aaa9..69fcee33df3b30bed27aed36ad35b370c5e7cb59 100644 (file)
@@ -1410,10 +1410,20 @@ private:
           }
         } else {
           SUBTRACET(seastore_tm, "retire extent place holder...", t);
-          auto retired_placeholder = cache->retire_absent_extent_addr(
-            t, pin.get_key(), original_paddr, original_len
-          )->template cast<RetiredExtentPlaceholder>();
-         ret.get_child_pos().link_child(retired_placeholder.get());
+          auto &child_pos = ret.get_child_pos();
+          auto laddr = pin.get_key();
+          std::ignore = cache->retire_absent_extent_addr_by_type(
+            t, laddr, original_paddr, original_len, pin.get_extent_type(),
+            [this, &child_pos, laddr, &t](auto &extent) mutable {
+              auto lextent = extent.template cast<LogicalChildNode>();
+              assert(extent.is_logical());
+              assert(!lextent->has_laddr());
+              assert(!extent.has_been_invalidated());
+              child_pos.link_child(lextent.get());
+              child_pos.invalidate_retired_placeholder(t, *cache, extent);
+              lextent->set_laddr(laddr);
+            }
+          );
         }
       }