Skip to content

Commit aa46a61

Browse files
zhscnMatan-B
authored andcommitted
crimson/os/seastore/BtreeLBAManager: split _alloc_extents implementation
Signed-off-by: Zhang Song <[email protected]> (cherry picked from commit 1ab74cd)
1 parent 64ebfc8 commit aa46a61

File tree

2 files changed

+238
-130
lines changed

2 files changed

+238
-130
lines changed

src/crimson/os/seastore/lba_manager/btree/btree_lba_manager.cc

Lines changed: 175 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,22 @@ SET_SUBSYS(seastore_lba);
1919
* - TRACE: read operations, DEBUG details
2020
*/
2121

22+
template <> struct fmt::formatter<
23+
crimson::os::seastore::lba_manager::btree::LBABtree::iterator>
24+
: public fmt::formatter<std::string_view>
25+
{
26+
using Iter = crimson::os::seastore::lba_manager::btree::LBABtree::iterator;
27+
28+
template <typename FmtCtx>
29+
auto format(const Iter &iter, FmtCtx &ctx) const
30+
-> decltype(ctx.out()) {
31+
if (iter.is_end()) {
32+
return fmt::format_to(ctx.out(), "end");
33+
}
34+
return fmt::format_to(ctx.out(), "{}~{}", iter.get_key(), iter.get_val());
35+
}
36+
};
37+
2238
namespace crimson::os::seastore {
2339

2440
template <typename T>
@@ -275,149 +291,179 @@ BtreeLBAManager::_get_mapping(
275291
});
276292
}
277293

278-
BtreeLBAManager::alloc_extents_ret
279-
BtreeLBAManager::_alloc_extents(
294+
BtreeLBAManager::search_insert_position_ret
295+
BtreeLBAManager::search_insert_position(
296+
op_context_t c,
297+
LBABtree &btree,
298+
laddr_t hint,
299+
extent_len_t length,
300+
alloc_policy_t policy)
301+
{
302+
LOG_PREFIX(BtreeLBAManager::search_insert_position);
303+
auto lookup_attempts = stats.num_alloc_extents_iter_nexts;
304+
using OptIter = std::optional<LBABtree::iterator>;
305+
return seastar::do_with(
306+
hint, OptIter(std::nullopt),
307+
[this, c, &btree, hint, length, lookup_attempts, policy, FNAME]
308+
(laddr_t &last_end, OptIter &insert_iter)
309+
{
310+
return LBABtree::iterate_repeat(
311+
c,
312+
btree.upper_bound_right(c, hint),
313+
[this, c, hint, length, lookup_attempts, policy,
314+
&last_end, &insert_iter, FNAME](auto &iter)
315+
{
316+
++stats.num_alloc_extents_iter_nexts;
317+
if (iter.is_end() ||
318+
iter.get_key() >= (last_end + length)) {
319+
if (policy == alloc_policy_t::deterministic) {
320+
ceph_assert(hint == last_end);
321+
}
322+
DEBUGT("hint: {}~0x{:x}, allocated laddr: {}, insert position: {}, "
323+
"done with {} attempts",
324+
c.trans, hint, length, last_end, iter,
325+
stats.num_alloc_extents_iter_nexts - lookup_attempts);
326+
insert_iter.emplace(iter);
327+
return search_insert_position_iertr::make_ready_future<
328+
seastar::stop_iteration>(seastar::stop_iteration::yes);
329+
}
330+
ceph_assert(policy == alloc_policy_t::linear_search);
331+
last_end = (iter.get_key() + iter.get_val().len).checked_to_laddr();
332+
TRACET("hint: {}~0x{:x}, current iter: {}, repeat ...",
333+
c.trans, hint, length, iter);
334+
return search_insert_position_iertr::make_ready_future<
335+
seastar::stop_iteration>(seastar::stop_iteration::no);
336+
}).si_then([&last_end, &insert_iter] {
337+
ceph_assert(insert_iter);
338+
return search_insert_position_iertr::make_ready_future<
339+
insert_position_t>(last_end, *std::move(insert_iter));
340+
});
341+
});
342+
}
343+
344+
BtreeLBAManager::alloc_mappings_ret
345+
BtreeLBAManager::alloc_contiguous_mappings(
280346
Transaction &t,
281347
laddr_t hint,
282-
std::vector<alloc_mapping_info_t> &alloc_infos)
348+
std::vector<alloc_mapping_info_t> &alloc_infos,
349+
alloc_policy_t policy)
283350
{
284351
ceph_assert(hint != L_ADDR_NULL);
285352
extent_len_t total_len = 0;
286-
#ifndef NDEBUG
287-
bool laddr_null = (alloc_infos.front().key == L_ADDR_NULL);
288-
laddr_t last_end = hint;
289353
for (auto &info : alloc_infos) {
290-
assert((info.key == L_ADDR_NULL) == (laddr_null));
291-
if (!laddr_null) {
292-
assert(info.key >= last_end);
293-
last_end = (info.key + info.value.len).checked_to_laddr();
294-
}
354+
assert(info.key == L_ADDR_NULL);
355+
total_len += info.value.len;
295356
}
296-
#endif
297-
if (alloc_infos.front().key == L_ADDR_NULL) {
298-
for (auto &info : alloc_infos) {
299-
total_len += info.value.len;
300-
}
301-
} else {
302-
auto end = alloc_infos.back().key + alloc_infos.back().value.len;
303-
total_len = end.get_byte_distance<extent_len_t>(hint);
304-
}
305-
306-
struct state_t {
307-
laddr_t last_end;
308357

309-
std::optional<typename LBABtree::iterator> insert_iter;
310-
std::optional<typename LBABtree::iterator> ret;
311-
312-
state_t(laddr_t hint) : last_end(hint) {}
313-
};
314-
315-
LOG_PREFIX(BtreeLBAManager::_alloc_extents);
316-
TRACET("{}~{}, hint={}, num of extents: {}",
317-
t, alloc_infos.front().value.pladdr, total_len, hint, alloc_infos.size());
358+
auto c = get_context(t);
359+
return with_btree<LBABtree>(
360+
cache,
361+
c,
362+
[this, c, hint, &alloc_infos, total_len, policy](auto &btree)
363+
{
364+
return search_insert_position(c, btree, hint, total_len, policy
365+
).si_then([this, c, &alloc_infos, &btree](insert_position_t res) {
366+
extent_len_t offset = 0;
367+
for (auto &info : alloc_infos) {
368+
info.key = (res.laddr + offset).checked_to_laddr();
369+
offset += info.value.len;
370+
}
371+
return insert_mappings(
372+
c, btree, std::move(res.insert_iter), alloc_infos);
373+
});
374+
});
375+
}
318376

377+
BtreeLBAManager::alloc_mappings_ret
378+
BtreeLBAManager::alloc_sparse_mappings(
379+
Transaction &t,
380+
laddr_t hint,
381+
std::vector<alloc_mapping_info_t> &alloc_infos,
382+
alloc_policy_t policy)
383+
{
384+
ceph_assert(hint != L_ADDR_NULL);
385+
#ifndef NDEBUG
386+
assert(alloc_infos.front().key != L_ADDR_NULL);
387+
for (size_t i = 1; i < alloc_infos.size(); i++) {
388+
auto &prev = alloc_infos[i - 1];
389+
auto &cur = alloc_infos[i];
390+
assert(cur.key != L_ADDR_NULL);
391+
assert(prev.key + prev.value.len <= cur.key);
392+
}
393+
#endif
394+
auto total_len = hint.get_byte_distance<extent_len_t>(
395+
alloc_infos.back().key + alloc_infos.back().value.len);
319396
auto c = get_context(t);
320-
stats.num_alloc_extents += alloc_infos.size();
321-
auto lookup_attempts = stats.num_alloc_extents_iter_nexts;
322-
return seastar::do_with(
323-
std::vector<LBAMappingRef>(),
324-
[this, FNAME, &alloc_infos, hint, &t, total_len, c,
325-
lookup_attempts](auto &rets) {
326-
return crimson::os::seastore::with_btree_state<LBABtree, state_t>(
327-
cache,
328-
c,
329-
hint,
330-
[this, c, hint, total_len, addr=alloc_infos.front().value.pladdr.get_paddr(), &rets,
331-
lookup_attempts, &t, &alloc_infos, FNAME](auto &btree, auto &state) {
332-
return LBABtree::iterate_repeat(
333-
c,
334-
btree.upper_bound_right(c, hint),
335-
[this, &state, total_len, addr, &t, hint,
336-
lookup_attempts, FNAME](auto &pos) {
337-
++stats.num_alloc_extents_iter_nexts;
338-
if (pos.is_end()) {
339-
DEBUGT("{}~{}, hint={}, state: end, done with {} attempts, insert at {}",
340-
t, addr, total_len, hint,
341-
stats.num_alloc_extents_iter_nexts - lookup_attempts,
342-
state.last_end);
343-
state.insert_iter = pos;
344-
return typename LBABtree::iterate_repeat_ret_inner(
345-
interruptible::ready_future_marker{},
346-
seastar::stop_iteration::yes);
347-
} else if (pos.get_key() >= (state.last_end + total_len)) {
348-
DEBUGT("{}~{}, hint={}, state: {}~{}, done with {} attempts, insert at {} -- {}",
349-
t, addr, total_len, hint,
350-
pos.get_key(), pos.get_val().len,
351-
stats.num_alloc_extents_iter_nexts - lookup_attempts,
352-
state.last_end,
353-
pos.get_val());
354-
state.insert_iter = pos;
355-
return typename LBABtree::iterate_repeat_ret_inner(
356-
interruptible::ready_future_marker{},
357-
seastar::stop_iteration::yes);
358-
} else {
359-
state.last_end = (pos.get_key() + pos.get_val().len).checked_to_laddr();
360-
TRACET("{}~{}, hint={}, state: {}~{}, repeat ... -- {}",
361-
t, addr, total_len, hint,
362-
pos.get_key(), pos.get_val().len,
363-
pos.get_val());
364-
return typename LBABtree::iterate_repeat_ret_inner(
365-
interruptible::ready_future_marker{},
366-
seastar::stop_iteration::no);
397+
return with_btree<LBABtree>(
398+
cache,
399+
c,
400+
[this, c, hint, &alloc_infos, total_len, policy](auto &btree)
401+
{
402+
return search_insert_position(c, btree, hint, total_len, policy
403+
).si_then([this, c, hint, &alloc_infos, &btree, policy](auto res) {
404+
if (policy != alloc_policy_t::deterministic) {
405+
for (auto &info : alloc_infos) {
406+
auto offset = info.key.get_byte_distance<extent_len_t>(hint);
407+
info.key = (res.laddr + offset).checked_to_laddr();
367408
}
368-
}).si_then([c, addr, hint, &btree, &state, &alloc_infos,
369-
total_len, &rets, FNAME] {
370-
return trans_intr::do_for_each(
371-
alloc_infos,
372-
[c, addr, hint, &btree, &state, FNAME,
373-
total_len, &rets, refcount](auto &alloc_info) {
374-
if (alloc_info.key != L_ADDR_NULL) {
375-
state.last_end = alloc_info.key;
409+
} // deterministic guarantees hint == res.laddr
410+
return insert_mappings(
411+
c, btree, std::move(res.insert_iter), alloc_infos);
412+
});
413+
});
414+
}
415+
416+
BtreeLBAManager::alloc_mappings_ret
417+
BtreeLBAManager::insert_mappings(
418+
op_context_t c,
419+
LBABtree &btree,
420+
LBABtree::iterator iter,
421+
std::vector<alloc_mapping_info_t> &alloc_infos)
422+
{
423+
return seastar::do_with(
424+
std::move(iter), std::list<LBACursorRef>(),
425+
[c, &btree, &alloc_infos]
426+
(LBABtree::iterator &iter, std::list<LBACursorRef> &ret)
427+
{
428+
return trans_intr::do_for_each(
429+
alloc_infos.begin(),
430+
alloc_infos.end(),
431+
[c, &btree, &iter, &ret](auto &info)
432+
{
433+
assert(info.key != L_ADDR_NULL);
434+
return btree.insert(
435+
c, iter, info.key, info.value
436+
).si_then([c, &iter, &ret, &info](auto p) {
437+
ceph_assert(p.second);
438+
iter = std::move(p.first);
439+
auto &leaf_node = *iter.get_leaf_node();
440+
leaf_node.insert_child_ptr(
441+
iter.get_leaf_pos(),
442+
info.extent,
443+
leaf_node.get_size() - 1 /*the size before the insert*/);
444+
if (is_valid_child_ptr(info.extent)) {
445+
ceph_assert(info.value.pladdr.is_paddr());
446+
assert(info.value.pladdr == iter.get_val().pladdr);
447+
assert(info.value.len == iter.get_val().len);
448+
assert(info.extent->is_logical());
449+
if (info.extent->has_laddr()) {
450+
// see TM::remap_pin()
451+
assert(info.key == info.extent->get_laddr());
452+
assert(info.key == iter.get_key());
453+
} else {
454+
// see TM::alloc_non_data_extent()
455+
// TM::alloc_data_extents()
456+
info.extent->set_laddr(iter.get_key());
376457
}
377-
return btree.insert(
378-
c,
379-
*state.insert_iter,
380-
state.last_end,
381-
alloc_info.value
382-
).si_then([&state, c, addr, total_len, hint, FNAME,
383-
&alloc_info, &rets](auto &&p) {
384-
auto [iter, inserted] = std::move(p);
385-
auto &leaf_node = *iter.get_leaf_node();
386-
leaf_node.insert_child_ptr(
387-
iter.get_leaf_pos(),
388-
alloc_info.extent,
389-
leaf_node.get_size() - 1 /*the size before the insert*/);
390-
TRACET("{}~{}, hint={}, inserted at {}",
391-
c.trans, addr, total_len, hint, state.last_end);
392-
if (is_valid_child_ptr(alloc_info.extent)) {
393-
ceph_assert(alloc_info.value.pladdr.is_paddr());
394-
assert(alloc_info.value.pladdr == iter.get_val().pladdr);
395-
assert(alloc_info.value.len == iter.get_val().len);
396-
assert(alloc_info.extent->is_logical());
397-
if (alloc_info.extent->has_laddr()) {
398-
// see TM::remap_pin()
399-
assert(alloc_info.key == alloc_info.extent->get_laddr());
400-
assert(alloc_info.key == iter.get_key());
401-
} else {
402-
// see TM::alloc_non_data_extent()
403-
// TM::alloc_data_extents()
404-
alloc_info.extent->set_laddr(iter.get_key());
405-
}
406-
}
407-
ceph_assert(inserted);
408-
rets.emplace_back(iter.get_pin(c));
409-
return iter.next(c).si_then([&state, &alloc_info](auto it) {
410-
state.insert_iter = it;
411-
if (alloc_info.key == L_ADDR_NULL) {
412-
state.last_end = (state.last_end + alloc_info.value.len).checked_to_laddr();
413-
}
414-
});
415-
});
458+
}
459+
ret.push_back(iter.get_cursor(c));
460+
return iter.next(c).si_then([&iter](auto p) {
461+
iter = std::move(p);
416462
});
417463
});
418-
}).si_then([&rets](auto &&state) {
419-
return alloc_extent_iertr::make_ready_future<
420-
std::vector<LBAMappingRef>>(std::move(rets));
464+
}).si_then([&ret] {
465+
return alloc_mappings_iertr::make_ready_future<
466+
std::list<LBACursorRef>>(std::move(ret));
421467
});
422468
});
423469
}

0 commit comments

Comments
 (0)