std::vector<alloc_mapping_info_t> &alloc_infos,
extent_ref_count_t refcount)
{
+ ceph_assert(hint != L_ADDR_NULL);
extent_len_t total_len = 0;
+#ifndef NDEBUG
+ bool laddr_null = (alloc_infos.front().key == L_ADDR_NULL);
+ laddr_t last_end = hint;
for (auto &info : alloc_infos) {
- total_len += info.len;
+ assert((info.key == L_ADDR_NULL) == (laddr_null));
+ if (!laddr_null) {
+ assert(info.key >= last_end);
+ last_end = info.key + info.len;
+ }
+ }
+#endif
+ if (alloc_infos.front().key == L_ADDR_NULL) {
+ for (auto &info : alloc_infos) {
+ total_len += info.len;
+ }
+ } else {
+ total_len = alloc_infos.back().key + alloc_infos.back().len - hint;
}
+
struct state_t {
laddr_t last_end;
alloc_infos,
[c, addr, hint, &btree, &state, FNAME,
total_len, &rets, refcount](auto &alloc_info) {
+ if (alloc_info.key != L_ADDR_NULL) {
+ state.last_end = alloc_info.key;
+ }
return btree.insert(
c,
*state.insert_iter,
c.trans, addr, total_len, hint, state.last_end);
if (alloc_info.extent) {
ceph_assert(alloc_info.val.is_paddr());
+ assert(alloc_info.val == iter.get_val().pladdr);
+ assert(alloc_info.len == iter.get_val().len);
+ if (alloc_info.extent->has_laddr()) {
+ assert(alloc_info.key == alloc_info.extent->get_laddr());
+ assert(alloc_info.key == iter.get_key());
+ } else {
+ alloc_info.extent->set_laddr(iter.get_key());
+ }
alloc_info.extent->set_laddr(iter.get_key());
}
ceph_assert(inserted);
rets.emplace_back(iter.get_pin(c));
return iter.next(c).si_then([&state, &alloc_info](auto it) {
state.insert_iter = it;
- state.last_end += alloc_info.len;
+ if (alloc_info.key == L_ADDR_NULL) {
+ state.last_end += alloc_info.len;
+ }
});
});
});
struct alloc_mapping_info_t {
+ laddr_t key = L_ADDR_NULL; // once assigned, the allocation to
+ // key must be exact and successful
extent_len_t len = 0;
pladdr_t val;
uint32_t checksum = 0;
LogicalCachedExtent* extent = nullptr;
+
+ static alloc_mapping_info_t create_zero(extent_len_t len) {
+ return {L_ADDR_NULL, len, P_ADDR_ZERO, 0, nullptr};
+ }
+ static alloc_mapping_info_t create_indirect(
+ laddr_t laddr,
+ extent_len_t len,
+ laddr_t intermediate_key) {
+ return {
+ laddr,
+ len,
+ intermediate_key,
+ 0, // crc will only be used and checked with LBA direct mappings
+ // also see pin_to_extent(_by_type)
+ nullptr};
+ }
+ static alloc_mapping_info_t create_direct(
+ laddr_t laddr,
+ extent_len_t len,
+ paddr_t paddr,
+ uint32_t checksum,
+ LogicalCachedExtent *extent) {
+ return {laddr, len, paddr, checksum, extent};
+ }
};
alloc_extent_ret reserve_region(
extent_len_t len) final
{
std::vector<alloc_mapping_info_t> alloc_infos = {
- alloc_mapping_info_t{len, P_ADDR_ZERO, 0, nullptr}};
+ alloc_mapping_info_t::create_zero(len)};
return seastar::do_with(
std::move(alloc_infos),
[&t, hint, this](auto &alloc_infos) {
{
// The real checksum will be updated upon transaction commit
assert(ext.get_last_committed_crc() == 0);
- std::vector<alloc_mapping_info_t> alloc_infos = {{
- ext.get_length(), ext.get_paddr(), ext.get_last_committed_crc(), &ext}};
+ assert(!ext.has_laddr());
+ std::vector<alloc_mapping_info_t> alloc_infos = {
+ alloc_mapping_info_t::create_direct(
+ L_ADDR_NULL,
+ ext.get_length(),
+ ext.get_paddr(),
+ ext.get_last_committed_crc(),
+ &ext)};
return seastar::do_with(
std::move(alloc_infos),
[this, &t, hint, refcount](auto &alloc_infos) {
{
std::vector<alloc_mapping_info_t> alloc_infos;
for (auto &extent : extents) {
- alloc_infos.emplace_back(alloc_mapping_info_t{
- extent->get_length(),
- pladdr_t(extent->get_paddr()),
- extent->get_last_committed_crc(),
- extent.get()});
+ alloc_infos.emplace_back(
+ alloc_mapping_info_t::create_direct(
+ extent->has_laddr() ? extent->get_laddr() : L_ADDR_NULL,
+ extent->get_length(),
+ extent->get_paddr(),
+ extent->get_last_committed_crc(),
+ extent.get()));
}
return seastar::do_with(
std::move(alloc_infos),
{
assert(intermediate_key != L_ADDR_NULL);
std::vector<alloc_mapping_info_t> alloc_infos = {
- alloc_mapping_info_t{
- len,
- intermediate_key,
- 0, // crc will only be used and checked with LBA direct mappings
- // also see pin_to_extent(_by_type)
- nullptr}};
+ alloc_mapping_info_t::create_indirect(L_ADDR_NULL, len, intermediate_key)};
return seastar::do_with(
std::move(alloc_infos),
[this, &t, laddr](auto &alloc_infos) {