@@ -396,40 +396,46 @@ class Cache : public ExtentTransViewRetriever,
396396 extent_len_t partial_off,
397397 extent_len_t partial_len,
398398 Func &&extent_init_func) {
399- CachedExtentRef ret;
400399 LOG_PREFIX (Cache::get_absent_extent);
401400
402401#ifndef NDEBUG
403- auto r = t.get_extent (offset, &ret);
404- if (r != Transaction::get_extent_ret::ABSENT) {
405- SUBERRORT (seastore_cache, " unexpected non-absent extent {}" , t, *ret);
406- ceph_abort ();
402+ {
403+ CachedExtentRef ret;
404+ auto r = t.get_extent (offset, &ret);
405+ if (r != Transaction::get_extent_ret::ABSENT) {
406+ SUBERRORT (seastore_cache, " unexpected non-absent extent {}" , t, *ret);
407+ ceph_abort ();
408+ }
407409 }
408410#endif
409411
410412 SUBTRACET (seastore_cache, " {} {}~0x{:x} is absent on t, query cache ..." ,
411413 t, T::TYPE, offset, length);
412414 const auto t_src = t.get_src ();
413- auto f = [&t, this , partial_off, partial_len, t_src](CachedExtent &ext) {
414- // XXX: is_stable_dirty() may not be linked in lba tree
415- assert (ext.is_stable ());
416- assert (T::TYPE == ext.get_type ());
417- cache_access_stats_t & access_stats = get_by_ext (
418- get_by_src (stats.access_by_src_ext , t_src),
419- T::TYPE);
420- ++access_stats.load_absent ;
421- ++stats.access .load_absent ;
422-
423- t.add_to_read_set (CachedExtentRef (&ext));
424- touch_extent_by_range (
425- ext, &t_src, t.get_cache_hint (),
426- partial_off, partial_len);
427- };
415+
416+ // partial read
417+ TCachedExtentRef<T> ret = CachedExtent::make_cached_extent_ref<T>(length);
418+ ret->init (CachedExtent::extent_state_t ::CLEAN,
419+ offset,
420+ PLACEMENT_HINT_NULL,
421+ NULL_GENERATION,
422+ TRANS_ID_NULL);
423+ SUBDEBUG (seastore_cache,
424+ " {} {}~0x{:x} is absent, add extent and reading range 0x{:x}~0x{:x} ... -- {}" ,
425+ T::TYPE, offset, length, partial_off, partial_len, *ret);
426+ add_extent (ret);
427+ extent_init_func (*ret);
428+ cache_access_stats_t & access_stats = get_by_ext (
429+ get_by_src (stats.access_by_src_ext , t_src),
430+ T::TYPE);
431+ ++access_stats.load_absent ;
432+ ++stats.access .load_absent ;
433+ t.add_to_read_set (CachedExtentRef (ret));
434+ touch_extent_by_range (
435+ *ret, &t_src, t.get_cache_hint (),
436+ partial_off, partial_len);
428437 return trans_intr::make_interruptible (
429- do_get_caching_extent<T>(
430- offset, length, partial_off, partial_len,
431- std::forward<Func>(extent_init_func), std::move (f), &t_src)
432- );
438+ read_extent<T>(std::move (ret), partial_off, partial_len, &t_src));
433439 }
434440
435441 /*
@@ -960,40 +966,7 @@ class Cache : public ExtentTransViewRetriever,
960966 paddr_t offset,
961967 laddr_t laddr,
962968 extent_len_t length,
963- extent_init_func_t &&extent_init_func
964- ) {
965- LOG_PREFIX (Cache::_get_absent_extent_by_type);
966-
967- #ifndef NDEBUG
968- CachedExtentRef ret;
969- auto r = t.get_extent (offset, &ret);
970- if (r != Transaction::get_extent_ret::ABSENT) {
971- SUBERRORT (seastore_cache, " unexpected non-absent extent {}" , t, *ret);
972- ceph_abort ();
973- }
974- #endif
975-
976- SUBTRACET (seastore_cache, " {} {}~0x{:x} {} is absent on t, query cache ..." ,
977- t, type, offset, length, laddr);
978- const auto t_src = t.get_src ();
979- auto f = [&t, this , t_src](CachedExtent &ext) {
980- // XXX: is_stable_dirty() may not be linked in lba tree
981- assert (ext.is_stable ());
982- cache_access_stats_t & access_stats = get_by_ext (
983- get_by_src (stats.access_by_src_ext , t_src),
984- ext.get_type ());
985- ++access_stats.load_absent ;
986- ++stats.access .load_absent ;
987-
988- t.add_to_read_set (CachedExtentRef (&ext));
989- touch_extent_fully (ext, &t_src, t.get_cache_hint ());
990- };
991- return trans_intr::make_interruptible (
992- do_get_caching_extent_by_type (
993- type, offset, laddr, length,
994- std::move (extent_init_func), std::move (f), &t_src)
995- );
996- }
969+ extent_init_func_t &&extent_init_func);
997970
998971 backref_entryrefs_by_seq_t backref_entryrefs_by_seq;
999972 backref_entry_mset_t backref_entry_mset;
@@ -1878,13 +1851,12 @@ class Cache : public ExtentTransViewRetriever,
18781851 // / also see do_read_extent_maybe_partial().
18791852 // /
18801853 // / May return an invalid extent due to transaction conflict.
1881- template <typename T>
1882- read_extent_ret<T> read_extent (
1883- TCachedExtentRef<T>&& extent,
1854+ get_extent_ertr::future<CachedExtentRef> _read_extent (
1855+ CachedExtentRef &&extent,
18841856 extent_len_t offset,
18851857 extent_len_t length,
1886- const Transaction::src_t * p_src
1887- ) {
1858+ const Transaction::src_t * p_src)
1859+ {
18881860 LOG_PREFIX (Cache::read_extent);
18891861 assert (extent->state == CachedExtent::extent_state_t ::EXIST_CLEAN ||
18901862 extent->state == CachedExtent::extent_state_t ::CLEAN);
@@ -1938,7 +1910,7 @@ class Cache : public ExtentTransViewRetriever,
19381910 offset, length, *extent);
19391911 }
19401912 extent->complete_io ();
1941- return get_extent_ertr::make_ready_future<TCachedExtentRef<T> >(
1913+ return get_extent_ertr::make_ready_future<CachedExtentRef >(
19421914 std::move (extent));
19431915 },
19441916 get_extent_ertr::pass_further{},
@@ -1948,6 +1920,19 @@ class Cache : public ExtentTransViewRetriever,
19481920 );
19491921 }
19501922
1923+ template <typename T>
1924+ read_extent_ret<T> read_extent (
1925+ TCachedExtentRef<T>&& extent,
1926+ extent_len_t offset,
1927+ extent_len_t length,
1928+ const Transaction::src_t * p_src
1929+ ) {
1930+ return _read_extent (std::move (extent), offset, length, p_src
1931+ ).safe_then ([](auto extent) {
1932+ return extent->template cast <T>();
1933+ });
1934+ }
1935+
19511936 // Extents in cache may contain placeholders
19521937 CachedExtentRef query_cache (paddr_t offset) {
19531938 if (auto iter = extents_index.find_offset (offset);
0 commit comments