static mkfs_ret mkfs(RootBlockRef &root_block, op_context_t c) {
assert(root_block->is_mutation_pending());
auto root_leaf = c.cache.template alloc_new_non_data_extent<leaf_node_t>(
- c.trans,
- node_size,
- placement_hint_t::HOT,
- INIT_GENERATION);
+ c.trans, node_size, {placement_hint_t::HOT, INIT_GENERATION});
root_leaf->set_size(0);
fixed_kv_node_meta_t<node_key_t> meta{min_max_t<node_key_t>::min, min_max_t<node_key_t>::max, 1};
root_leaf->set_meta(meta);
assert(is_lba_backref_node(e->get_type()));
auto do_rewrite = [&](auto &fixed_kv_extent) {
+ auto opt = Cache::alloc_option_t {
+ fixed_kv_extent.get_user_hint(),
+ // get target rewrite generation
+ fixed_kv_extent.get_rewrite_generation()
+ };
auto n_fixed_kv_extent = c.cache.template alloc_new_non_data_extent<
std::remove_reference_t<decltype(fixed_kv_extent)>
>(
c.trans,
fixed_kv_extent.get_length(),
- fixed_kv_extent.get_user_hint(),
- // get target rewrite generation
- fixed_kv_extent.get_rewrite_generation());
+ opt);
n_fixed_kv_extent->rewrite(c.trans, fixed_kv_extent, 0);
SUBTRACET(
if (split_from == iter.get_depth()) {
assert(iter.is_full());
auto nroot = c.cache.template alloc_new_non_data_extent<internal_node_t>(
- c.trans, node_size, placement_hint_t::HOT, INIT_GENERATION);
+ c.trans, node_size, {placement_hint_t::HOT, INIT_GENERATION});
fixed_kv_node_meta_t<node_key_t> meta{
min_max_t<node_key_t>::min, min_max_t<node_key_t>::max, iter.get_depth() + 1};
nroot->set_meta(meta);
std::tuple<Ref, Ref, NODE_KEY>
make_split_children(op_context_t c) {
auto left = c.cache.template alloc_new_non_data_extent<node_type_t>(
- c.trans, node_size, placement_hint_t::HOT, INIT_GENERATION);
+ c.trans, node_size, {placement_hint_t::HOT, INIT_GENERATION});
auto right = c.cache.template alloc_new_non_data_extent<node_type_t>(
- c.trans, node_size, placement_hint_t::HOT, INIT_GENERATION);
+ c.trans, node_size, {placement_hint_t::HOT, INIT_GENERATION});
this->split_child_ptrs(c.trans, *left, *right);
auto pivot = this->split_into(*left, *right);
left->range = left->get_meta();
op_context_t c,
Ref &right) {
auto replacement = c.cache.template alloc_new_non_data_extent<node_type_t>(
- c.trans, node_size, placement_hint_t::HOT, INIT_GENERATION);
+ c.trans, node_size, {placement_hint_t::HOT, INIT_GENERATION});
replacement->merge_child_ptrs(
c.trans, static_cast<node_type_t&>(*this), *right);
replacement->merge_from(*this, *right->template cast<node_type_t>());
ceph_assert(_right->get_type() == this->get_type());
auto &right = *_right->template cast<node_type_t>();
auto replacement_left = c.cache.template alloc_new_non_data_extent<node_type_t>(
- c.trans, node_size, placement_hint_t::HOT, INIT_GENERATION);
+ c.trans, node_size, {placement_hint_t::HOT, INIT_GENERATION});
auto replacement_right = c.cache.template alloc_new_non_data_extent<node_type_t>(
- c.trans, node_size, placement_hint_t::HOT, INIT_GENERATION);
+ c.trans, node_size, {placement_hint_t::HOT, INIT_GENERATION});
// We should do full merge if pivot_idx == right.get_size().
ceph_assert(pivot_idx != right.get_size());
std::tuple<Ref, Ref, NODE_KEY>
make_split_children(op_context_t c) {
auto left = c.cache.template alloc_new_non_data_extent<node_type_t>(
- c.trans, node_size, placement_hint_t::HOT, INIT_GENERATION);
+ c.trans, node_size, {placement_hint_t::HOT, INIT_GENERATION});
auto right = c.cache.template alloc_new_non_data_extent<node_type_t>(
- c.trans, node_size, placement_hint_t::HOT, INIT_GENERATION);
+ c.trans, node_size, {placement_hint_t::HOT, INIT_GENERATION});
this->on_split(c.trans, *left, *right);
auto pivot = this->split_into(*left, *right);
left->range = left->get_meta();
op_context_t c,
Ref &right) {
auto replacement = c.cache.template alloc_new_non_data_extent<node_type_t>(
- c.trans, node_size, placement_hint_t::HOT, INIT_GENERATION);
+ c.trans, node_size, {placement_hint_t::HOT, INIT_GENERATION});
replacement->on_merge(c.trans, static_cast<node_type_t&>(*this), *right);
replacement->merge_from(*this, *right->template cast<node_type_t>());
replacement->range = replacement->get_meta();
ceph_assert(_right->get_type() == this->get_type());
auto &right = *_right->template cast<node_type_t>();
auto replacement_left = c.cache.template alloc_new_non_data_extent<node_type_t>(
- c.trans, node_size, placement_hint_t::HOT, INIT_GENERATION);
+ c.trans, node_size, {placement_hint_t::HOT, INIT_GENERATION});
auto replacement_right = c.cache.template alloc_new_non_data_extent<node_type_t>(
- c.trans, node_size, placement_hint_t::HOT, INIT_GENERATION);
+ c.trans, node_size, {placement_hint_t::HOT, INIT_GENERATION});
this->on_balance(
c.trans,
SUBDEBUGT(seastore_cache, "allocate {} 0x{:x}B, hint={}, gen={}",
t, type, length, hint, rewrite_gen_printer_t{gen});
ceph_assert(get_extent_category(type) == data_category_t::METADATA);
+ auto opt = alloc_option_t{hint, gen};
switch (type) {
case extent_types_t::ROOT:
ceph_assert(0 == "ROOT is never directly alloc'd");
return CachedExtentRef();
case extent_types_t::LADDR_INTERNAL:
- return alloc_new_non_data_extent<lba::LBAInternalNode>(t, length, hint, gen);
+ return alloc_new_non_data_extent<lba::LBAInternalNode>(t, length, opt);
case extent_types_t::LADDR_LEAF:
return alloc_new_non_data_extent<lba::LBALeafNode>(
- t, length, hint, gen);
+ t, length, opt);
case extent_types_t::ROOT_META:
return alloc_new_non_data_extent<RootMetaBlock>(
- t, length, hint, gen);
+ t, length, opt);
case extent_types_t::ONODE_BLOCK_STAGED:
return alloc_new_non_data_extent<onode::SeastoreNodeExtent>(
- t, length, hint, gen);
+ t, length, opt);
case extent_types_t::OMAP_INNER:
return alloc_new_non_data_extent<omap_manager::OMapInnerNode>(
- t, length, hint, gen);
+ t, length, opt);
case extent_types_t::OMAP_LEAF:
return alloc_new_non_data_extent<omap_manager::OMapLeafNode>(
- t, length, hint, gen);
+ t, length, opt);
case extent_types_t::COLL_BLOCK:
return alloc_new_non_data_extent<collection_manager::CollectionNode>(
- t, length, hint, gen);
+ t, length, opt);
case extent_types_t::TEST_BLOCK_PHYSICAL:
- return alloc_new_non_data_extent<TestBlockPhysical>(t, length, hint, gen);
+ return alloc_new_non_data_extent<TestBlockPhysical>(t, length, opt);
case extent_types_t::LOG_NODE:
return alloc_new_non_data_extent<log_manager::LogNode>(
- t, length, hint, gen);
+ t, length, opt);
case extent_types_t::NONE: {
ceph_assert(0 == "NONE is an invalid extent type");
return CachedExtentRef();
case extent_types_t::OBJECT_DATA_BLOCK:
{
auto extents = alloc_new_data_extents<
- ObjectDataBlock>(t, length, hint, gen);
+ ObjectDataBlock>(t, length, {hint, gen});
res.insert(res.begin(), extents.begin(), extents.end());
}
return res;
case extent_types_t::TEST_BLOCK:
{
auto extents = alloc_new_data_extents<
- TestBlock>(t, length, hint, gen);
+ TestBlock>(t, length, {hint, gen});
res.insert(res.begin(), extents.begin(), extents.end());
}
return res;
}
}
+ using alloc_option_t = ExtentPlacementManager::alloc_option_t;
/**
* alloc_new_non_data_extent
*
TCachedExtentRef<T> alloc_new_non_data_extent(
Transaction &t, ///< [in, out] current transaction
extent_len_t length, ///< [in] length
- placement_hint_t hint, ///< [in] user hint
-#ifdef UNIT_TESTS_BUILT
- rewrite_gen_t gen, ///< [in] rewrite generation
- std::optional<paddr_t> epaddr = std::nullopt ///< [in] paddr fed by callers
-#else
- rewrite_gen_t gen
-#endif
+ alloc_option_t opt
) {
LOG_PREFIX(Cache::alloc_new_non_data_extent);
- SUBTRACET(seastore_cache, "allocate {} 0x{:x}B, hint={}, gen={}",
- t, T::TYPE, length, hint, rewrite_gen_printer_t{gen});
-#ifdef UNIT_TESTS_BUILT
- auto result = epm.alloc_new_non_data_extent(t, T::TYPE, length, hint, gen, epaddr);
-#else
- auto result = epm.alloc_new_non_data_extent(t, T::TYPE, length, hint, gen);
-#endif
+ SUBTRACET(seastore_cache, "allocate {} 0x{:x}B, opt.hint={}, gen={}",
+ t, T::TYPE, length, opt.hint, rewrite_gen_printer_t{opt.gen});
+ auto result = epm.alloc_new_non_data_extent(t, T::TYPE, length, opt);
if (!result) {
SUBERRORT(seastore_cache, "insufficient space", t);
std::rethrow_exception(crimson::ct_error::enospc::exception_ptr());
epm.dynamic_max_rewrite_generation));
ret->init(CachedExtent::extent_state_t::INITIAL_WRITE_PENDING,
result->paddr,
- hint,
+ opt.hint,
result->gen,
t.get_trans_id());
t.add_fresh_extent(ret);
SUBDEBUGT(seastore_cache,
"allocated {} 0x{:x}B extent at {}, hint={}, gen={} -- {}",
t, T::TYPE, length, result->paddr,
- hint, rewrite_gen_printer_t{result->gen}, *ret);
+ opt.hint, rewrite_gen_printer_t{result->gen}, *ret);
return ret;
}
/**
std::vector<TCachedExtentRef<T>> alloc_new_data_extents(
Transaction &t, ///< [in, out] current transaction
extent_len_t length, ///< [in] length
- placement_hint_t hint, ///< [in] user hint
-#ifdef UNIT_TESTS_BUILT
- rewrite_gen_t gen, ///< [in] rewrite generation
- std::optional<paddr_t> epaddr = std::nullopt ///< [in] paddr fed by callers
-#else
- rewrite_gen_t gen
-#endif
+ alloc_option_t opt
) {
LOG_PREFIX(Cache::alloc_new_data_extents);
SUBTRACET(seastore_cache, "allocate {} 0x{:x}B, hint={}, gen={}",
- t, T::TYPE, length, hint, rewrite_gen_printer_t{gen});
-#ifdef UNIT_TESTS_BUILT
- auto results = epm.alloc_new_data_extents(t, T::TYPE, length, hint, gen, epaddr);
-#else
- auto results = epm.alloc_new_data_extents(t, T::TYPE, length, hint, gen);
-#endif
+ t, T::TYPE, length, opt.hint, rewrite_gen_printer_t{opt.gen});
+ auto results = epm.alloc_new_data_extents(t, T::TYPE, length, opt);
if (results.empty()) {
SUBERRORT(seastore_cache, "insufficient space", t);
std::rethrow_exception(crimson::ct_error::enospc::exception_ptr());
epm.dynamic_max_rewrite_generation));
ret->init(CachedExtent::extent_state_t::INITIAL_WRITE_PENDING,
result.paddr,
- hint,
+ opt.hint,
result.gen,
t.get_trans_id());
t.add_fresh_extent(ret);
SUBDEBUGT(seastore_cache,
"allocated {} 0x{:x}B extent at {}, hint={}, gen={} -- {}",
t, T::TYPE, length, result.paddr,
- hint, rewrite_gen_printer_t{result.gen}, *ret);
+ opt.hint, rewrite_gen_printer_t{result.gen}, *ret);
extents.emplace_back(std::move(ret));
}
return extents;
return background_process.start_background();
}
+ struct alloc_option_t {
+ placement_hint_t hint;
+ rewrite_gen_t gen;
+#ifdef UNIT_TESTS_BUILT
+ std::optional<paddr_t> external_paddr = std::nullopt;
+#endif
+ };
struct alloc_result_t {
paddr_t paddr;
bufferptr bp;
Transaction& t,
extent_types_t type,
extent_len_t length,
- placement_hint_t hint,
-#ifdef UNIT_TESTS_BUILT
- rewrite_gen_t gen,
- std::optional<paddr_t> external_paddr = std::nullopt
-#else
- rewrite_gen_t gen
-#endif
+ alloc_option_t opt
) {
- assert(hint < placement_hint_t::NUM_HINTS);
- assert(is_target_rewrite_generation(gen, dynamic_max_rewrite_generation));
- assert(gen == INIT_GENERATION || hint == placement_hint_t::REWRITE);
+ assert(opt.hint < placement_hint_t::NUM_HINTS);
+ assert(is_target_rewrite_generation(opt.gen, dynamic_max_rewrite_generation));
+ assert(opt.gen == INIT_GENERATION || opt.hint == placement_hint_t::REWRITE);
data_category_t category = get_extent_category(type);
- gen = adjust_generation(category, type, hint, gen);
+ opt.gen = adjust_generation(category, type, opt.hint, opt.gen);
paddr_t addr;
#ifdef UNIT_TESTS_BUILT
- if (unlikely(external_paddr.has_value())) {
- assert(external_paddr->is_fake());
- addr = *external_paddr;
- } else if (gen == INLINE_GENERATION) {
-#else
- if (gen == INLINE_GENERATION) {
+ if (unlikely(opt.external_paddr.has_value())) {
+ assert(opt.external_paddr->is_fake());
+ addr = *opt.external_paddr;
+ } else
#endif
+ if (opt.gen == INLINE_GENERATION) {
addr = make_record_relative_paddr(0);
} else {
assert(category == data_category_t::METADATA);
- addr = get_writer(hint, category, gen)->alloc_paddr(length);
+ addr = get_writer(opt.hint, category, opt.gen)->alloc_paddr(length);
}
assert(!(category == data_category_t::DATA));
// according to the allocator.
auto bp = create_extent_ptr_zero(length);
- return alloc_result_t{addr, std::move(bp), gen};
+ return alloc_result_t{addr, std::move(bp), opt.gen};
}
std::list<alloc_result_t> alloc_new_data_extents(
Transaction& t,
extent_types_t type,
extent_len_t length,
- placement_hint_t hint,
-#ifdef UNIT_TESTS_BUILT
- rewrite_gen_t gen,
- std::optional<paddr_t> external_paddr = std::nullopt
-#else
- rewrite_gen_t gen
-#endif
+ alloc_option_t opt
) {
LOG_PREFIX(ExtentPlacementManager::alloc_new_data_extents);
- assert(hint < placement_hint_t::NUM_HINTS);
- assert(is_target_rewrite_generation(gen, dynamic_max_rewrite_generation));
- assert(gen == INIT_GENERATION || hint == placement_hint_t::REWRITE);
+ assert(opt.hint < placement_hint_t::NUM_HINTS);
+ assert(is_target_rewrite_generation(opt.gen, dynamic_max_rewrite_generation));
+ assert(opt.gen == INIT_GENERATION || opt.hint == placement_hint_t::REWRITE);
data_category_t category = get_extent_category(type);
- gen = adjust_generation(category, type, hint, gen);
- assert(gen != INLINE_GENERATION);
+ opt.gen = adjust_generation(category, type, opt.hint, opt.gen);
+ assert(opt.gen != INLINE_GENERATION);
// XXX: bp might be extended to point to different memory (e.g. PMem)
// according to the allocator.
std::list<alloc_result_t> allocs;
#ifdef UNIT_TESTS_BUILT
- if (unlikely(external_paddr.has_value())) {
- assert(external_paddr->is_fake());
+ if (unlikely(opt.external_paddr.has_value())) {
+ assert(opt.external_paddr->is_fake());
auto bp = create_extent_ptr_zero(length);
- allocs.emplace_back(alloc_result_t{*external_paddr, std::move(bp), gen});
- } else {
-#else
- {
+ allocs.emplace_back(alloc_result_t{*opt.external_paddr, std::move(bp), opt.gen});
+ } else
#endif
+ {
assert(category == data_category_t::DATA);
- auto addrs = get_writer(hint, category, gen)->alloc_paddrs(length);
+ auto addrs = get_writer(opt.hint, category, opt.gen)->alloc_paddrs(length);
for (auto &ext : addrs) {
auto left = ext.len;
while (left > 0) {
auto start = ext.start.is_delayed()
? ext.start
: ext.start + (ext.len - left);
- allocs.emplace_back(alloc_result_t{start, std::move(bp), gen});
+ allocs.emplace_back(alloc_result_t{start, std::move(bp), opt.gen});
SUBDEBUGT(seastore_epm,
- "allocated {} 0x{:x}B extent at {}, hint={}, gen={}",
- t, type, len, start, hint, gen);
+ "allocated {} 0x{:x}B extent at {}, opt.hint={}, opt.gen={}",
+ t, type, len, start, opt.hint, opt.gen);
left -= len;
}
}
SUBDEBUGT(seastore_tm, "{} hint {}~0x{:x} phint={} ...",
t, T::TYPE, laddr_hint, len, placement_hint);
auto ext = cache->alloc_new_non_data_extent<T>(
- t,
- len,
- placement_hint,
- INIT_GENERATION);
+ t, len, {placement_hint, INIT_GENERATION});
// user must initialize the logical extent themselves.
assert(is_user_transaction(t.get_src()));
ext->set_seen_by_users();
SUBDEBUGT(seastore_tm, "{} hint {}~0x{:x} phint={} ...",
t, T::TYPE, laddr_hint, len, placement_hint);
auto exts = cache->alloc_new_data_extents<T>(
- t,
- len,
- placement_hint,
- INIT_GENERATION);
+ t, len, {placement_hint, INIT_GENERATION});
// user must initialize the logical extent themselves
assert(is_user_transaction(t.get_src()));
for (auto& ext : exts) {
check.emplace(addr, get_map_val(len, TestBlock::TYPE));
lba_btree_update([=, this](auto &btree, auto &t) {
auto extents = cache->alloc_new_data_extents<TestBlock>(
- t,
- TestBlock::SIZE,
- placement_hint_t::HOT,
- 0,
- get_paddr());
+ t, TestBlock::SIZE, {placement_hint_t::HOT, 0, false, get_paddr()});
return seastar::do_with(
std::move(extents),
[this, addr, &t, len, &btree](auto &extents) {
cache->alloc_new_non_data_extent<TestBlockPhysical>(
*t.t,
TestBlockPhysical::SIZE,
- placement_hint_t::HOT,
- 0);
+ {placement_hint_t::HOT, 0});
};
return t;
}
*t.t,
[=, this](auto &t) {
auto extents = cache->alloc_new_data_extents<TestBlock>(
- t,
- TestBlock::SIZE,
- placement_hint_t::HOT,
- 0,
- get_paddr());
+ t, TestBlock::SIZE, {placement_hint_t::HOT, 0, false, get_paddr()});
return seastar::do_with(
std::vector<LogicalChildNodeRef>(
extents.begin(), extents.end()),
auto extent = cache->alloc_new_non_data_extent<TestBlockPhysical>(
*t,
TestBlockPhysical::SIZE,
- placement_hint_t::HOT,
- 0);
+ {placement_hint_t::HOT, 0});
extent->set_contents('c');
csum = extent->calc_crc32c();
submit_transaction(std::move(t)).get();
auto extent = cache->alloc_new_non_data_extent<TestBlockPhysical>(
*t,
TestBlockPhysical::SIZE,
- placement_hint_t::HOT,
- 0);
+ {placement_hint_t::HOT, 0});
extent->set_contents('c');
csum = extent->calc_crc32c();
auto reladdr = extent->get_paddr();