logger().debug("FlatCollectionManager: {}", __func__);
return tm.alloc_non_data_extent<CollectionNode>(
- t, L_ADDR_MIN, MIN_FLAT_BLOCK_SIZE
+ t, laddr_hint_t::create_global_md_hint(), MIN_FLAT_BLOCK_SIZE
).si_then([](auto&& root_extent) {
coll_root_t coll_root = coll_root_t(
root_extent->get_laddr(),
// collections would create a ton of other problems as well
assert(new_size < MAX_FLAT_BLOCK_SIZE);
return tm.alloc_non_data_extent<CollectionNode>(
- t, L_ADDR_MIN, new_size
+ t, laddr_hint_t::create_global_md_hint(), new_size
).si_then([=, this, &coll_root, &t] (auto &&root_extent) {
coll_root.update(root_extent->get_laddr(), root_extent->get_length());
BtreeLBAManager::search_insert_position(
op_context_t c,
LBABtree &btree,
- laddr_t hint,
+ laddr_hint_t hint,
extent_len_t length,
alloc_policy_t policy)
{
LOG_PREFIX(BtreeLBAManager::search_insert_position);
auto lookup_attempts = stats.num_alloc_extents_iter_nexts;
using OptIter = std::optional<LBABtree::iterator>;
+ // TODO: handle conflict condition and policy
return seastar::do_with(
- hint, OptIter(std::nullopt),
+ hint.addr, OptIter(std::nullopt),
[this, c, &btree, hint, length, lookup_attempts, policy, FNAME]
(laddr_t &last_end, OptIter &insert_iter)
{
return LBABtree::iterate_repeat(
c,
- btree.upper_bound_right(c, hint),
+ btree.upper_bound_right(c, hint.addr),
[this, c, hint, length, lookup_attempts, policy,
&last_end, &insert_iter, FNAME](auto &iter)
{
if (iter.is_end() ||
iter.get_key() >= (last_end + length)) {
if (policy == alloc_policy_t::deterministic) {
- ceph_assert(hint == last_end);
+ ceph_assert(hint.addr == last_end);
}
DEBUGT("hint: {}~0x{:x}, allocated laddr: {}, insert position: {}, "
"done with {} attempts",
BtreeLBAManager::alloc_mappings_ret
BtreeLBAManager::alloc_contiguous_mappings(
Transaction &t,
- laddr_t hint,
+ laddr_hint_t hint,
std::vector<alloc_mapping_info_t> &alloc_infos,
alloc_policy_t policy)
{
- ceph_assert(hint != L_ADDR_NULL);
+ ceph_assert(hint.addr != L_ADDR_NULL);
extent_len_t total_len = 0;
for (auto &info : alloc_infos) {
assert(info.key == L_ADDR_NULL);
BtreeLBAManager::alloc_mappings_ret
BtreeLBAManager::alloc_sparse_mappings(
Transaction &t,
- laddr_t hint,
+ laddr_hint_t hint,
std::vector<alloc_mapping_info_t> &alloc_infos,
alloc_policy_t policy)
{
- ceph_assert(hint != L_ADDR_NULL);
+ ceph_assert(hint.addr != L_ADDR_NULL);
#ifndef NDEBUG
assert(alloc_infos.front().key != L_ADDR_NULL);
for (size_t i = 1; i < alloc_infos.size(); i++) {
assert(prev.key + prev.value.len <= cur.key);
}
#endif
- auto total_len = hint.get_byte_distance<extent_len_t>(
+ auto total_len = hint.addr.get_byte_distance<extent_len_t>(
alloc_infos.back().key + alloc_infos.back().value.len);
auto c = get_context(t);
return with_btree<LBABtree>(
).si_then([this, c, hint, &alloc_infos, &btree, policy](auto res) {
if (policy != alloc_policy_t::deterministic) {
for (auto &info : alloc_infos) {
- auto offset = info.key.get_byte_distance<extent_len_t>(hint);
+ auto offset = info.key.get_byte_distance<extent_len_t>(hint.addr);
info.key = (res.laddr + offset).checked_to_laddr();
}
} // deterministic guarantees hint == res.laddr
alloc_extent_ret reserve_region(
Transaction &t,
- laddr_t hint,
+ laddr_hint_t hint,
extent_len_t len) final
{
std::vector<alloc_mapping_info_t> alloc_infos = {
alloc_extent_ret alloc_extent(
Transaction &t,
- laddr_t hint,
+ laddr_hint_t hint,
LogicalChildNode &ext,
extent_ref_count_t refcount) final
{
alloc_extents_ret alloc_extents(
Transaction &t,
- laddr_t hint,
+ laddr_hint_t hint,
std::vector<LogicalChildNodeRef> extents,
extent_ref_count_t refcount) final
{
search_insert_position_ret search_insert_position(
op_context_t c,
LBABtree &btree,
- laddr_t hint,
+ laddr_hint_t hint,
extent_len_t length,
alloc_policy_t policy);
*/
alloc_mappings_ret alloc_contiguous_mappings(
Transaction &t,
- laddr_t hint,
+ laddr_hint_t hint,
std::vector<alloc_mapping_info_t> &alloc_infos,
alloc_policy_t policy);
*/
alloc_mappings_ret alloc_sparse_mappings(
Transaction &t,
- laddr_t hint,
+ laddr_hint_t hint,
std::vector<alloc_mapping_info_t> &alloc_infos,
alloc_policy_t policy);
using alloc_extent_ret = alloc_extent_iertr::future<LBACursorRef>;
virtual alloc_extent_ret alloc_extent(
Transaction &t,
- laddr_t hint,
+ laddr_hint_t hint,
LogicalChildNode &nextent,
extent_ref_count_t refcount) = 0;
std::vector<LBACursorRef>>;
virtual alloc_extents_ret alloc_extents(
Transaction &t,
- laddr_t hint,
+ laddr_hint_t hint,
std::vector<LogicalChildNodeRef> extents,
extent_ref_count_t refcount) = 0;
/*
virtual alloc_extent_ret reserve_region(
Transaction &t,
- laddr_t hint,
+ laddr_hint_t hint,
extent_len_t len) = 0;
/*
ctx.tm.get_block_size() - data.tailbl->length());
auto extents = co_await ctx.tm.alloc_data_extents<ObjectDataBlock>(
ctx.t,
- (overwrite_range.aligned_end - ctx.tm.get_block_size()).checked_to_laddr(),
+ laddr_hint_t::create_as_fixed(
+ (overwrite_range.aligned_end - ctx.tm.get_block_size()).checked_to_laddr()),
ctx.tm.get_block_size(),
std::move(zero_pos)
).handle_error_interruptible(
ctx.tm.get_block_size() - data.headbl->length());
auto extents = co_await ctx.tm.alloc_data_extents<ObjectDataBlock>(
ctx.t,
- overwrite_range.aligned_begin,
+ laddr_hint_t::create_as_fixed(overwrite_range.aligned_begin),
ctx.tm.get_block_size(),
std::move(zero_pos)
).handle_error_interruptible(
data.merge_head(ctx.tm.get_block_size());
auto extents = co_await ctx.tm.alloc_data_extents<ObjectDataBlock>(
ctx.t,
- overwrite_range.aligned_begin,
+ laddr_hint_t::create_as_fixed(overwrite_range.aligned_begin),
ctx.tm.get_block_size(),
std::move(write_pos)
).handle_error_interruptible(
assert(data.bl);
return ctx.tm.alloc_data_extents<ObjectDataBlock>(
ctx.t,
- overwrite_range.aligned_begin,
+ laddr_hint_t::create_as_fixed(overwrite_range.aligned_begin),
overwrite_range.aligned_end.template get_byte_distance<
extent_len_t>(overwrite_range.aligned_begin),
std::move(write_pos)
virtual void unset_need_cow(Transaction&) = 0;
virtual void swap_layout(Transaction&, Onode&) = 0;
- laddr_t get_metadata_hint(uint64_t block_size = laddr_t::UNIT_SIZE) const {
- // TODO: return laddr_hint_t
- return get_hint(block_size, /*is_metadata*/true).addr;
+ laddr_hint_t get_metadata_hint(uint64_t block_size = laddr_t::UNIT_SIZE) const {
+ return get_hint(block_size, /*is_metadata*/true);
}
- laddr_t get_data_hint(uint64_t block_size = laddr_t::UNIT_SIZE) const {
- // TODO: return laddr_hint_t
- return get_hint(block_size, /*is_metadata*/false).addr;
+ laddr_hint_t get_data_hint(uint64_t block_size = laddr_t::UNIT_SIZE) const {
+ return get_hint(block_size, /*is_metadata*/false);
}
laddr_hint_t get_metadata_clone_hint(uint64_t block_size = laddr_t::UNIT_SIZE) const {
return get_clone_hint(block_size, /*is_metadata*/true);
ceph_assert(refcount != 0);
auto cursor = co_await lba_manager->alloc_extent(
t,
- (extent->get_laddr() + off).checked_to_laddr(),
+ laddr_hint_t::create_as_fixed(
+ (extent->get_laddr() + off).checked_to_laddr()),
*nextent,
refcount
);
template <typename T>
alloc_extent_ret<T> alloc_non_data_extent(
Transaction &t,
- laddr_t laddr_hint,
+ laddr_hint_t laddr_hint,
extent_len_t len,
placement_hint_t placement_hint = placement_hint_t::HOT) {
static_assert(is_logical_metadata_type(T::TYPE));
template <typename T>
alloc_extents_ret<T> alloc_data_extents(
Transaction &t,
- laddr_t laddr_hint,
+ laddr_hint_t laddr_hint,
extent_len_t len,
std::optional<LBAMapping> pos = std::nullopt,
placement_hint_t placement_hint = placement_hint_t::HOT) {
}
if (pos) {
// laddr_hint is determined
- auto off = laddr_hint;
+ assert(laddr_hint.condition == laddr_conflict_condition_t::all_at_never);
+ auto off = laddr_hint.addr;
for (auto &extent : exts) {
extent->set_laddr(off);
off = (off + extent->get_length()).checked_to_laddr();
using reserve_extent_ret = reserve_extent_iertr::future<LBAMapping>;
reserve_extent_ret reserve_region(
Transaction &t,
- laddr_t hint,
+ laddr_hint_t hint,
extent_len_t len) {
LOG_PREFIX(TransactionManager::reserve_region);
SUBDEBUGT(seastore_tm, "hint {}~0x{:x} ...", t, hint, len);
alloc_extents_iertr::future<std::vector<TCachedExtentRef<T>>>
alloc_extents(
Transaction &t,
- laddr_t hint,
+ laddr_hint_t hint,
extent_len_t len,
int num) {
LOG_PREFIX(TransactionManager::alloc_extents);
using init_root_meta_ret = init_root_meta_iertr::future<>;
init_root_meta_ret init_root_meta(Transaction &t) {
return alloc_non_data_extent<RootMetaBlock>(
- t, L_ADDR_MIN, RootMetaBlock::SIZE
+ t, laddr_hint_t::create_as_fixed(L_ADDR_MIN), RootMetaBlock::SIZE
).si_then([this, &t](auto meta) {
meta->set_meta(RootMetaBlock::meta_t{});
return cache->get_root(t
crimson::ct_error::pass_further_all{}
).si_then([this, offset, &t, &ptr] {
logger().debug("dec_ref complete");
- return tm->alloc_data_extents<TestBlock>(t, laddr_t::from_byte_offset(offset), ptr.length());
+ return tm->alloc_data_extents<TestBlock>(
+ t,
+ laddr_hint_t::create_as_fixed(laddr_t::from_byte_offset(offset)),
+ ptr.length());
}).si_then([this, offset, &t, &ptr](auto extents) mutable {
boost::ignore_unused(offset); // avoid clang warning;
auto off = offset;
auto alloc_mappings(
test_transaction_t &t,
- laddr_t hint,
+ laddr_t addr,
size_t len) {
auto rets = with_trans_intr(
*t.t,
return seastar::do_with(
std::vector<LogicalChildNodeRef>(
extents.begin(), extents.end()),
- [this, &t, hint](auto &extents) {
+ [this, &t, addr](auto &extents) {
+ laddr_hint_t hint;
+ hint.addr = addr;
+ hint.condition = laddr_conflict_condition_t::all_at_object_content;
+ hint.policy = laddr_conflict_policy_t::linear_search;
return lba_manager->alloc_extents(t, hint, std::move(extents), EXTENT_DEFAULT_REF_COUNT);
});
}).unsafe_get();
TestBlockRef alloc_extent(
test_transaction_t &t,
- laddr_t hint,
+ laddr_t addr,
extent_len_t len,
char contents) {
auto extents = with_trans_intr(*(t.t), [&](auto& trans) {
+ laddr_hint_t hint;
+ hint.addr = addr;
+ hint.condition = laddr_conflict_condition_t::all_at_object_content;
+ hint.policy = laddr_conflict_policy_t::gen_random;
+ hint.block_size = laddr_t::UNIT_SIZE;
return tm->alloc_data_extents<TestBlock>(trans, hint, len);
}).unsafe_get();
assert(extents.size() == 1);
extent_len_t allocated_len = 0;
extent->set_contents(contents);
EXPECT_FALSE(test_mappings.contains(extent->get_laddr(), t.mapping_delta));
- test_mappings.alloced(hint, *extent, t.mapping_delta);
+ test_mappings.alloced(addr, *extent, t.mapping_delta);
allocated_len += extent->get_length();
EXPECT_EQ(len, allocated_len);
return extent;
std::vector<TestBlockRef> alloc_extents(
test_transaction_t &t,
- laddr_t hint,
+ laddr_t addr,
extent_len_t len,
char contents) {
auto extents = with_trans_intr(*(t.t), [&](auto& trans) {
+ laddr_hint_t hint;
+ hint.addr = addr;
+ hint.condition = laddr_conflict_condition_t::all_at_object_content;
+ hint.policy = laddr_conflict_policy_t::gen_random;
+ hint.block_size = laddr_t::UNIT_SIZE;
return tm->alloc_data_extents<TestBlock>(trans, hint, len);
}).unsafe_get();
size_t length = 0;
extent->set_contents(contents);
length += extent->get_length();
EXPECT_FALSE(test_mappings.contains(extent->get_laddr(), t.mapping_delta));
- test_mappings.alloced(hint, *extent, t.mapping_delta);
+ test_mappings.alloced(addr, *extent, t.mapping_delta);
exts.push_back(extent->template cast<TestBlock>());
}
EXPECT_EQ(len, length);
void alloc_extents_deemed_fail(
test_transaction_t &t,
- laddr_t hint,
+ laddr_t addr,
extent_len_t len,
char contents)
{
std::cout << __func__ << std::endl;
auto fut = with_trans_intr(*(t.t), [&](auto& trans) {
+ laddr_hint_t hint;
+ hint.addr = addr;
+ hint.condition = laddr_conflict_condition_t::all_at_object_content;
+ hint.policy = laddr_conflict_policy_t::gen_random;
+ hint.block_size = laddr_t::UNIT_SIZE;
return tm->alloc_data_extents<TestBlock>(trans, hint, len);
});
fut.unsafe_wait();
boost::make_counting_iterator(0),
boost::make_counting_iterator(num),
[&t, this, size](auto) {
+ laddr_hint_t hint;
+ hint.addr = L_ADDR_MIN;
+ hint.condition = laddr_conflict_condition_t::all_at_object_content;
+ hint.policy = laddr_conflict_policy_t::gen_random;
+ hint.block_size = laddr_t::UNIT_SIZE;
return tm->alloc_data_extents<TestBlock>(
- *(t.t), L_ADDR_MIN, size
+ *(t.t), hint, size
).si_then([&t, this, size](auto extents) {
extent_len_t length = 0;
for (auto &extent : extents) {
o_len - new_offset - new_len)
}
).si_then([this, new_offset, new_len, o_laddr, &t, &bl](auto ret) {
- return tm->alloc_data_extents<TestBlock>(t, (o_laddr + new_offset).checked_to_laddr(), new_len
+ return tm->alloc_data_extents<TestBlock>(
+ t,
+ laddr_hint_t::create_as_fixed(
+ (o_laddr + new_offset).checked_to_laddr()),
+ new_len
).si_then([this, ret = std::move(ret), new_len,
new_offset, o_laddr, &t, &bl](auto extents) mutable {
assert(extents.size() == 1);
o_len - new_offset - new_len)
}
).si_then([this, new_offset, new_len, o_laddr, &t, &bl](auto ret) {
- return tm->alloc_data_extents<TestBlock>(t, (o_laddr + new_offset).checked_to_laddr(), new_len
+ return tm->alloc_data_extents<TestBlock>(
+ t,
+ laddr_hint_t::create_as_fixed(
+ (o_laddr + new_offset).checked_to_laddr()),
+ new_len
).si_then([this, ret = std::move(ret), new_offset, new_len,
o_laddr, &t, &bl](auto extents) mutable {
assert(extents.size() == 1);
new_offset)
}
).si_then([this, new_offset, new_len, o_laddr, &t, &bl](auto ret) {
- return tm->alloc_data_extents<TestBlock>(t, (o_laddr + new_offset).checked_to_laddr(), new_len
+ return tm->alloc_data_extents<TestBlock>(
+ t,
+ laddr_hint_t::create_as_fixed(
+ (o_laddr + new_offset).checked_to_laddr()),
+ new_len
).si_then([this, ret = std::move(ret), new_len, o_laddr, &t, &bl]
(auto extents) mutable {
assert(extents.size() == 1);
void test_clone_and_remap_pin() {
run_async([this] {
disable_max_extent_size();
- laddr_t l_offset = get_laddr_hint(32 << 10);
+ laddr_t l_offset = L_ADDR_MIN.with_local_clone_id(10);
size_t l_len = 32 << 10;
- laddr_t r_offset = get_laddr_hint(64 << 10);
+ laddr_t r_offset = L_ADDR_MIN.with_local_clone_id(20);
size_t r_len = 32 << 10;
- laddr_t l_clone_offset = get_laddr_hint(96 << 10);
- laddr_t r_clone_offset = get_laddr_hint(128 << 10);
+ laddr_t l_clone_offset = L_ADDR_MIN.with_local_clone_id(30);
+ laddr_t r_clone_offset = L_ADDR_MIN.with_local_clone_id(40);
{
auto t = create_transaction();
auto lext = alloc_extent(t, l_offset, l_len);