]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore/cache: get_absent_extent doesn't need to query cache
authorXuehan Xu <xuxuehan@qianxin.com>
Tue, 22 Jul 2025 01:29:28 +0000 (09:29 +0800)
committerXuehan Xu <xxhdx1985126@gmail.com>
Tue, 12 Aug 2025 05:43:25 +0000 (13:43 +0800)
anymore

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

index 640be6771308fc247666bcbe673599895b310761..cb1d43e0e7ac58f8a7e7faf055eb406ff6e93d01 100644 (file)
@@ -2264,6 +2264,118 @@ Cache::get_root_ret Cache::get_root(Transaction &t)
   }
 }
 
+Cache::get_extent_by_type_ret
+Cache::_get_absent_extent_by_type(
+  Transaction &t,
+  extent_types_t type,
+  paddr_t offset,
+  laddr_t laddr,
+  extent_len_t length,
+  extent_init_func_t &&extent_init_func)
+{
+  LOG_PREFIX(Cache::_get_absent_extent_by_type);
+
+#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();
+    }
+    assert(!query_cache(offset));
+  }
+#endif
+
+  const auto t_src = t.get_src();
+
+  // partial read
+  CachedExtentRef ret;
+  switch (type) {
+  case extent_types_t::ROOT:
+    ceph_assert(0 == "ROOT is never directly read");
+    break;
+  case extent_types_t::BACKREF_INTERNAL:
+    ret = CachedExtent::make_cached_extent_ref<
+      backref::BackrefInternalNode>(length);
+    break;
+  case extent_types_t::BACKREF_LEAF:
+    ret = CachedExtent::make_cached_extent_ref<
+      backref::BackrefLeafNode>(length);
+    break;
+  case extent_types_t::LADDR_INTERNAL:
+    ret = CachedExtent::make_cached_extent_ref<
+      lba::LBAInternalNode>(length);
+    break;
+  case extent_types_t::LADDR_LEAF:
+    ret = CachedExtent::make_cached_extent_ref<
+      lba::LBALeafNode>(length);
+    break;
+  case extent_types_t::ROOT_META:
+    ret = CachedExtent::make_cached_extent_ref<
+      RootMetaBlock>(length);
+    break;
+  case extent_types_t::OMAP_INNER:
+    ret = CachedExtent::make_cached_extent_ref<
+      omap_manager::OMapInnerNode>(length);
+    break;
+  case extent_types_t::OMAP_LEAF:
+    ret = CachedExtent::make_cached_extent_ref<
+      omap_manager::OMapLeafNode>(length);
+    break;
+  case extent_types_t::COLL_BLOCK:
+    ret = CachedExtent::make_cached_extent_ref<
+      collection_manager::CollectionNode>(length);
+    break;
+  case extent_types_t::ONODE_BLOCK_STAGED:
+    ret = CachedExtent::make_cached_extent_ref<
+      onode::SeastoreNodeExtent>(length);
+    break;
+  case extent_types_t::OBJECT_DATA_BLOCK:
+    ret = CachedExtent::make_cached_extent_ref<ObjectDataBlock>(length);
+    break;
+  case extent_types_t::RETIRED_PLACEHOLDER:
+    ceph_assert(0 == "impossible");
+    break;
+  case extent_types_t::TEST_BLOCK:
+    ret = CachedExtent::make_cached_extent_ref<TestBlock>(length);
+    break;
+  case extent_types_t::TEST_BLOCK_PHYSICAL:
+    ret = CachedExtent::make_cached_extent_ref<TestBlockPhysical>(length);
+    break;
+  case extent_types_t::NONE:
+    ceph_assert(0 == "NONE is an invalid extent type");
+    break;
+  default:
+    ceph_assert(0 == "impossible");
+  }
+  ret->init(CachedExtent::extent_state_t::CLEAN,
+           offset,
+           PLACEMENT_HINT_NULL,
+           NULL_GENERATION,
+           TRANS_ID_NULL);
+  DEBUGT("{} length=0x{:x} is absent, add extent ... -- {}",
+    t, type, length, *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),
+    type);
+  ++access_stats.load_absent;
+  ++stats.access.load_absent;
+  t.add_to_read_set(CachedExtentRef(ret));
+  touch_extent_fully(*ret, &t_src, t.get_cache_hint());
+  return trans_intr::make_interruptible(
+    read_extent(std::move(ret), 0, length, &t_src
+    ).safe_then([laddr](auto extent) {
+      if (extent->is_logical()) {
+       extent->template cast<LogicalCachedExtent>()->set_laddr(laddr);
+      }
+      return extent;
+    })
+  );
+}
+
 Cache::get_extent_ertr::future<CachedExtentRef>
 Cache::do_get_caching_extent_by_type(
   extent_types_t type,
index 1259f52eac0de26b29dc9770ca75f89e0453f7b0..71f94ad059aa8b102998c2ecff83ca00124e8683 100644 (file)
@@ -396,40 +396,46 @@ public:
     extent_len_t partial_off,
     extent_len_t partial_len,
     Func &&extent_init_func) {
-    CachedExtentRef ret;
     LOG_PREFIX(Cache::get_absent_extent);
 
 #ifndef NDEBUG
-    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();
+    {
+      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} is absent on t, query cache ...",
              t, T::TYPE, offset, length);
     const auto t_src = t.get_src();
-    auto f = [&t, this, partial_off, partial_len, t_src](CachedExtent &ext) {
-      // XXX: is_stable_dirty() may not be linked in lba tree
-      assert(ext.is_stable());
-      assert(T::TYPE == ext.get_type());
-      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(&ext));
-      touch_extent_by_range(
-       ext, &t_src, t.get_cache_hint(),
-       partial_off, partial_len);
-    };
+
+    // 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);
+    SUBDEBUG(seastore_cache,
+       "{} {}~0x{:x} is absent, add extent and reading range 0x{:x}~0x{:x} ... -- {}",
+       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);
     return trans_intr::make_interruptible(
-      do_get_caching_extent<T>(
-        offset, length, partial_off, partial_len,
-        std::forward<Func>(extent_init_func), std::move(f), &t_src)
-    );
+      read_extent<T>(std::move(ret), partial_off, partial_len, &t_src));
   }
 
   /*
@@ -960,40 +966,7 @@ private:
     paddr_t offset,
     laddr_t laddr,
     extent_len_t length,
-    extent_init_func_t &&extent_init_func
-  ) {
-    LOG_PREFIX(Cache::_get_absent_extent_by_type);
-
-#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} {} is absent on t, query cache ...",
-             t, type, offset, length, laddr);
-    const auto t_src = t.get_src();
-    auto f = [&t, this, t_src](CachedExtent &ext) {
-      // XXX: is_stable_dirty() may not be linked in lba tree
-      assert(ext.is_stable());
-      cache_access_stats_t& access_stats = get_by_ext(
-        get_by_src(stats.access_by_src_ext, t_src),
-        ext.get_type());
-      ++access_stats.load_absent;
-      ++stats.access.load_absent;
-
-      t.add_to_read_set(CachedExtentRef(&ext));
-      touch_extent_fully(ext, &t_src, t.get_cache_hint());
-    };
-    return trans_intr::make_interruptible(
-      do_get_caching_extent_by_type(
-       type, offset, laddr, length,
-       std::move(extent_init_func), std::move(f), &t_src)
-    );
-  }
+    extent_init_func_t &&extent_init_func);
 
   backref_entryrefs_by_seq_t backref_entryrefs_by_seq;
   backref_entry_mset_t backref_entry_mset;
@@ -1878,13 +1851,12 @@ private:
   /// also see do_read_extent_maybe_partial().
   ///
   /// May return an invalid extent due to transaction conflict.
-  template <typename T>
-  read_extent_ret<T> read_extent(
-    TCachedExtentRef<T>&& extent,
+  get_extent_ertr::future<CachedExtentRef> _read_extent(
+    CachedExtentRef &&extent,
     extent_len_t offset,
     extent_len_t length,
-    const Transaction::src_t* p_src
-  {
+    const Transaction::src_t *p_src)
+  {
     LOG_PREFIX(Cache::read_extent);
     assert(extent->state == CachedExtent::extent_state_t::EXIST_CLEAN ||
            extent->state == CachedExtent::extent_state_t::CLEAN);
@@ -1938,7 +1910,7 @@ private:
             offset, length, *extent);
         }
         extent->complete_io();
-        return get_extent_ertr::make_ready_future<TCachedExtentRef<T>>(
+        return get_extent_ertr::make_ready_future<CachedExtentRef>(
           std::move(extent));
       },
       get_extent_ertr::pass_further{},
@@ -1948,6 +1920,19 @@ private:
     );
   }
 
+  template <typename T>
+  read_extent_ret<T> read_extent(
+    TCachedExtentRef<T>&& extent,
+    extent_len_t offset,
+    extent_len_t length,
+    const Transaction::src_t* p_src
+  ) {
+    return _read_extent(std::move(extent), offset, length, p_src
+    ).safe_then([](auto extent) {
+      return extent->template cast<T>();
+    });
+  }
+
   // Extents in cache may contain placeholders
   CachedExtentRef query_cache(paddr_t offset) {
     if (auto iter = extents_index.find_offset(offset);