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()
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
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);
}
}
+ /**
+ */
+ 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
*
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
*
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();
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:
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;
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);
+ }
+ );
}
}
}
} 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);
+ }
+ );
}
}