From 415059c92f4d57c772b42d9f60d2b507786154e0 Mon Sep 17 00:00:00 2001 From: Xuehan Xu Date: Tue, 22 Jul 2025 09:29:28 +0800 Subject: [PATCH] crimson/os/seastore/cache: get_absent_extent doesn't need to query cache anymore Signed-off-by: Xuehan Xu --- src/crimson/os/seastore/cache.cc | 112 ++++++++++++++++++++++++++++++ src/crimson/os/seastore/cache.h | 113 ++++++++++++++----------------- 2 files changed, 161 insertions(+), 64 deletions(-) diff --git a/src/crimson/os/seastore/cache.cc b/src/crimson/os/seastore/cache.cc index 640be677130..cb1d43e0e7a 100644 --- a/src/crimson/os/seastore/cache.cc +++ b/src/crimson/os/seastore/cache.cc @@ -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(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(length); + break; + case extent_types_t::TEST_BLOCK_PHYSICAL: + ret = CachedExtent::make_cached_extent_ref(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()->set_laddr(laddr); + } + return extent; + }) + ); +} + Cache::get_extent_ertr::future Cache::do_get_caching_extent_by_type( extent_types_t type, diff --git a/src/crimson/os/seastore/cache.h b/src/crimson/os/seastore/cache.h index 1259f52eac0..71f94ad059a 100644 --- a/src/crimson/os/seastore/cache.h +++ b/src/crimson/os/seastore/cache.h @@ -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 ret = CachedExtent::make_cached_extent_ref(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( - offset, length, partial_off, partial_len, - std::forward(extent_init_func), std::move(f), &t_src) - ); + read_extent(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 - read_extent_ret read_extent( - TCachedExtentRef&& extent, + get_extent_ertr::future _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>( + return get_extent_ertr::make_ready_future( std::move(extent)); }, get_extent_ertr::pass_further{}, @@ -1948,6 +1920,19 @@ private: ); } + template + read_extent_ret read_extent( + TCachedExtentRef&& 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(); + }); + } + // Extents in cache may contain placeholders CachedExtentRef query_cache(paddr_t offset) { if (auto iter = extents_index.find_offset(offset); -- 2.39.5