@@ -93,8 +93,8 @@ Cache::retire_extent_ret Cache::retire_extent_addr(
9393 return retire_extent_iertr::now ();
9494}
9595
96- void Cache::retire_absent_extent_addr (
97- Transaction &t, paddr_t paddr, extent_len_t length)
96+ CachedExtentRef Cache::retire_absent_extent_addr (
97+ Transaction &t, laddr_t laddr, paddr_t paddr, extent_len_t length)
9898{
9999 assert (paddr.is_absolute ());
100100
@@ -112,10 +112,12 @@ void Cache::retire_absent_extent_addr(
112112 ext->init (
113113 CachedExtent::extent_state_t ::CLEAN, paddr,
114114 PLACEMENT_HINT_NULL, NULL_GENERATION, TRANS_ID_NULL);
115+ static_cast <RetiredExtentPlaceholder&>(*ext).set_laddr (laddr);
115116 DEBUGT (" retire {}~0x{:x} as placeholder, add extent -- {}" ,
116117 t, paddr, length, *ext);
117118 add_extent (ext);
118119 t.add_absent_to_retired_set (ext);
120+ return ext;
119121}
120122
121123void Cache::dump_contents ()
@@ -740,7 +742,9 @@ void Cache::add_extent(CachedExtentRef ref)
740742 assert (ref->rewrite_generation == NULL_GENERATION);
741743 assert (ref->get_paddr ().is_absolute () ||
742744 ref->get_paddr ().is_root ());
743- extents_index.insert (*ref);
745+ if (booting) {
746+ extents_index.insert (*ref);
747+ }
744748}
745749
746750void Cache::mark_dirty (CachedExtentRef ref)
@@ -882,7 +886,9 @@ void Cache::remove_extent(
882886 assert (ref->get_paddr ().is_absolute ());
883887 pinboard->remove (*ref);
884888 }
885- extents_index.erase (*ref);
889+ if (ref->is_linked_to_index ()) {
890+ extents_index.erase (*ref);
891+ }
886892}
887893
888894void Cache::commit_retire_extent (
@@ -904,7 +910,9 @@ void Cache::commit_replace_extent(
904910 assert (next->get_paddr () == prev->get_paddr ());
905911 assert (next->get_paddr ().is_absolute () || next->get_paddr ().is_root ());
906912 assert (next->version == prev->version + 1 );
907- extents_index.replace (*next, *prev);
913+ if (booting) {
914+ extents_index.replace (*next, *prev);
915+ }
908916
909917 const auto t_src = t.get_src ();
910918 if (is_root_type (prev->get_type ())) {
@@ -2213,28 +2221,18 @@ Cache::get_next_dirty_extents_ret Cache::get_next_dirty_extents(
22132221 return ;
22142222 }
22152223
2216- CachedExtentRef on_transaction;
2217- auto result = t.get_extent (ext->get_paddr (), &on_transaction);
2218- if (result == Transaction::get_extent_ret::ABSENT) {
2219- DEBUGT (" extent is absent on t -- {}" , t, *ext);
2220- t.add_to_read_set (ext);
2221- if (is_root_type (ext->get_type ())) {
2222- if (t.root ) {
2223- assert (&*t.root == &*ext);
2224- ceph_assert (0 == " t.root would have to already be in the read set" );
2225- } else {
2226- assert (&*ext == &*root);
2227- t.root = root;
2228- }
2224+ DEBUGT (" adding dirty extent {}" , t, *ext);
2225+ t.add_to_read_set (ext);
2226+ if (is_root_type (ext->get_type ())) {
2227+ if (t.root ) {
2228+ assert (&*t.root == &*ext);
2229+ ceph_assert (0 == " t.root would have to already be in the read set" );
2230+ } else {
2231+ assert (&*ext == &*root);
2232+ t.root = root;
22292233 }
2230- ret.push_back (ext);
2231- } else if (result == Transaction::get_extent_ret::PRESENT) {
2232- DEBUGT (" extent is present on t -- {}, on t {}" , t, *ext, *on_transaction);
2233- ret.push_back (on_transaction);
2234- } else {
2235- assert (result == Transaction::get_extent_ret::RETIRED);
2236- DEBUGT (" extent is retired on t -- {}" , t, *ext);
22372234 }
2235+ ret.push_back (ext);
22382236 });
22392237 }).then_interruptible ([&ret] {
22402238 return std::move (ret);
@@ -2262,6 +2260,118 @@ Cache::get_root_ret Cache::get_root(Transaction &t)
22622260 }
22632261}
22642262
2263+ Cache::get_extent_by_type_ret
2264+ Cache::_get_absent_extent_by_type (
2265+ Transaction &t,
2266+ extent_types_t type,
2267+ paddr_t offset,
2268+ laddr_t laddr,
2269+ extent_len_t length,
2270+ extent_init_func_t &&extent_init_func)
2271+ {
2272+ LOG_PREFIX (Cache::_get_absent_extent_by_type);
2273+
2274+ #ifndef NDEBUG
2275+ {
2276+ CachedExtentRef ret;
2277+ auto r = t.get_extent (offset, &ret);
2278+ if (r != Transaction::get_extent_ret::ABSENT) {
2279+ SUBERRORT (seastore_cache, " unexpected non-absent extent {}" , t, *ret);
2280+ ceph_abort ();
2281+ }
2282+ assert (!query_cache (offset));
2283+ }
2284+ #endif
2285+
2286+ const auto t_src = t.get_src ();
2287+
2288+ // partial read
2289+ CachedExtentRef ret;
2290+ switch (type) {
2291+ case extent_types_t ::ROOT:
2292+ ceph_assert (0 == " ROOT is never directly read" );
2293+ break ;
2294+ case extent_types_t ::BACKREF_INTERNAL:
2295+ ret = CachedExtent::make_cached_extent_ref<
2296+ backref::BackrefInternalNode>(length);
2297+ break ;
2298+ case extent_types_t ::BACKREF_LEAF:
2299+ ret = CachedExtent::make_cached_extent_ref<
2300+ backref::BackrefLeafNode>(length);
2301+ break ;
2302+ case extent_types_t ::LADDR_INTERNAL:
2303+ ret = CachedExtent::make_cached_extent_ref<
2304+ lba::LBAInternalNode>(length);
2305+ break ;
2306+ case extent_types_t ::LADDR_LEAF:
2307+ ret = CachedExtent::make_cached_extent_ref<
2308+ lba::LBALeafNode>(length);
2309+ break ;
2310+ case extent_types_t ::ROOT_META:
2311+ ret = CachedExtent::make_cached_extent_ref<
2312+ RootMetaBlock>(length);
2313+ break ;
2314+ case extent_types_t ::OMAP_INNER:
2315+ ret = CachedExtent::make_cached_extent_ref<
2316+ omap_manager::OMapInnerNode>(length);
2317+ break ;
2318+ case extent_types_t ::OMAP_LEAF:
2319+ ret = CachedExtent::make_cached_extent_ref<
2320+ omap_manager::OMapLeafNode>(length);
2321+ break ;
2322+ case extent_types_t ::COLL_BLOCK:
2323+ ret = CachedExtent::make_cached_extent_ref<
2324+ collection_manager::CollectionNode>(length);
2325+ break ;
2326+ case extent_types_t ::ONODE_BLOCK_STAGED:
2327+ ret = CachedExtent::make_cached_extent_ref<
2328+ onode::SeastoreNodeExtent>(length);
2329+ break ;
2330+ case extent_types_t ::OBJECT_DATA_BLOCK:
2331+ ret = CachedExtent::make_cached_extent_ref<ObjectDataBlock>(length);
2332+ break ;
2333+ case extent_types_t ::RETIRED_PLACEHOLDER:
2334+ ceph_assert (0 == " impossible" );
2335+ break ;
2336+ case extent_types_t ::TEST_BLOCK:
2337+ ret = CachedExtent::make_cached_extent_ref<TestBlock>(length);
2338+ break ;
2339+ case extent_types_t ::TEST_BLOCK_PHYSICAL:
2340+ ret = CachedExtent::make_cached_extent_ref<TestBlockPhysical>(length);
2341+ break ;
2342+ case extent_types_t ::NONE:
2343+ ceph_assert (0 == " NONE is an invalid extent type" );
2344+ break ;
2345+ default :
2346+ ceph_assert (0 == " impossible" );
2347+ }
2348+ ret->init (CachedExtent::extent_state_t ::CLEAN,
2349+ offset,
2350+ PLACEMENT_HINT_NULL,
2351+ NULL_GENERATION,
2352+ TRANS_ID_NULL);
2353+ DEBUGT (" {} length=0x{:x} is absent, add extent ... -- {}" ,
2354+ t, type, length, *ret);
2355+ add_extent (ret);
2356+ extent_init_func (*ret);
2357+ cache_access_stats_t & access_stats = get_by_ext (
2358+ get_by_src (stats.access_by_src_ext , t_src),
2359+ type);
2360+ ++access_stats.load_absent ;
2361+ ++stats.access .load_absent ;
2362+ t.add_to_read_set (CachedExtentRef (ret));
2363+ touch_extent_fully (*ret, &t_src, t.get_cache_hint ());
2364+ return trans_intr::make_interruptible (
2365+ read_extent (std::move (ret), 0 , length, &t_src
2366+ ).safe_then ([laddr](auto extent) {
2367+ if (extent->is_logical ()) {
2368+ extent->template cast <LogicalCachedExtent>()->set_laddr (laddr);
2369+ }
2370+ return extent;
2371+ })
2372+ );
2373+ }
2374+
22652375Cache::get_extent_ertr::future<CachedExtentRef>
22662376Cache::do_get_caching_extent_by_type (
22672377 extent_types_t type,
0 commit comments