DEBUGT("remove mapping: {}", t, backref_entry.paddr);
return remove_mapping(
t,
- backref_entry.paddr
+ backref_entry.paddr,
+ backref_entry.type
).si_then([](auto&&) {
return seastar::now();
}).handle_error_interruptible(
BtreeBackrefManager::remove_mapping_ret
BtreeBackrefManager::remove_mapping(
Transaction &t,
- paddr_t addr)
+ paddr_t addr,
+ extent_types_t type)
{
auto c = get_context(t);
return with_btree<BackrefBtree>(
cache,
c,
- [c, addr](auto &btree) mutable {
+ [c, addr, type](auto &btree) mutable {
return btree.lower_bound(
c, addr
- ).si_then([&btree, c, addr](auto iter)
+ ).si_then([&btree, c, addr, type](auto iter)
-> remove_mapping_ret {
if (iter.is_end() || iter.get_key() != addr) {
LOG_PREFIX(BtreeBackrefManager::remove_mapping);
remove_mapping_result_t>(remove_mapping_result_t());
}
+ auto val = iter.get_val();
+ ceph_assert(type == val.type);
auto ret = remove_mapping_result_t{
iter.get_key(),
- iter.get_val().len,
- iter.get_val().laddr};
+ val.len,
+ val.laddr};
return btree.remove(
c,
iter
remove_mapping_ret remove_mapping(
Transaction &t,
- paddr_t offset) final;
+ paddr_t offset,
+ extent_types_t type) final;
scan_mapped_space_ret scan_mapped_space(
Transaction &t,
using remove_mapping_ret = remove_mapping_iertr::future<remove_mapping_result_t>;
virtual remove_mapping_ret remove_mapping(
Transaction &t,
- paddr_t offset) = 0;
+ paddr_t offset,
+ extent_types_t type) = 0;
/**
* scan all extents in both tree and cache,
<< ", type=" << (extent_types_t)v.type
<< ", checksum=0x" << v.checksum
<< ", refcount=" << std::dec << v.refcount
+ << ", type=" << v.type
<< ")";
}
pladdr_le_t pladdr;
extent_ref_count_le_t refcount{0};
checksum_le_t checksum{0};
- extent_types_le_t type = 0;
+ extent_types_le_t type{EXTENT_TYPES_MAX};
lba_map_val_le_t() = default;
lba_map_val_le_t(const lba_map_val_le_t &) = default;
pladdr(pladdr_le_t(val.pladdr)),
refcount(val.refcount),
checksum(val.checksum),
- type((extent_types_le_t)val.type) {}
+ type(static_cast<extent_types_le_t>(val.type)) {}
operator lba_map_val_t() const {
return lba_map_val_t{
pladdr,
refcount,
checksum,
- (extent_types_t)type};
+ static_cast<extent_types_t>(type)};
}
};
c.trans,
laddr,
iter.is_end() ? min_max_t<node_key_t>::max : iter.get_key());
+ if constexpr (std::is_same_v<node_key_t, laddr_t>) {
+ // avoid unexpect default extent type for lba btree
+ assert(val.type != extent_types_t::ROOT);
+ }
return seastar::do_with(
iter,
[this, c, laddr, val, child](auto &ret) {
Transaction &t,
LBACursorRef cursor,
laddr_t addr,
- extent_len_t len)
+ extent_len_t len,
+ extent_types_t type)
{
LOG_PREFIX(BtreeLBAManager::reserve_region);
DEBUGT("{} {}~{}", t, *cursor, addr, len);
pladdr_t{P_ADDR_ZERO},
EXTENT_DEFAULT_REF_COUNT,
0,
- extent_types_t::NONE};
+ type};
auto p = co_await btree.insert(
c, iter, addr, val,
get_reserved_ptr<LBALeafNode, laddr_t>()
assert(orig_indirect ||
(orig_val.pladdr.is_paddr() &&
orig_val.pladdr.get_paddr().is_absolute()));
+ auto type = cursor->get_extent_type();
cursor = co_await update_mapping_refcount(
c.trans, cursor, -1);
iter = btree.make_partial_iter(c, *cursor);
val.refcount = EXTENT_DEFAULT_REF_COUNT;
// Checksum will be updated when the committing the transaction
val.checksum = CRC_NULL;
+ val.type = type;
// committing the transaction
auto p = co_await btree.insert(
c, iter, new_key, std::move(val),
Transaction &t,
LBACursorRef pos,
laddr_t laddr,
- extent_len_t len) final;
+ extent_len_t len,
+ extent_types_t type) final;
alloc_extent_ret reserve_region(
Transaction &t,
laddr_hint_t hint,
- extent_len_t len) final
+ extent_len_t len,
+ extent_types_t type) final
{
std::vector<alloc_mapping_info_t> alloc_infos = {
- alloc_mapping_info_t::create_zero(len)};
+ alloc_mapping_info_t::create_zero(len, type)};
auto cursors = co_await alloc_contiguous_mappings(
t, hint, alloc_infos);
assert(cursors.size() == 1);
return value.pladdr.is_laddr();
}
- static alloc_mapping_info_t create_zero(extent_len_t len) {
+ static alloc_mapping_info_t create_zero(
+ extent_len_t len,
+ extent_types_t type) {
return {
L_ADDR_NULL,
{
pladdr_t(P_ADDR_ZERO),
EXTENT_DEFAULT_REF_COUNT,
0,
- extent_types_t::NONE
+ type
}};
}
static alloc_mapping_info_t create_indirect(
EXTENT_DEFAULT_REF_COUNT,
0, // crc will only be used and checked with LBA direct mappings
// also see pin_to_extent(_by_type)
- extent_types_t::NONE
+ // only OBJECT_DATA_BLOCK support indirect mapping for now
+ extent_types_t::OBJECT_DATA_BLOCK
}};
}
static alloc_mapping_info_t create_direct(
checksum_t checksum,
LogicalChildNode& extent) {
return {
- laddr,
- {len,
- pladdr_t(paddr),
- refcount,
- checksum,
- extent.get_type()},
- &extent};
+ laddr,
+ {len, pladdr_t(paddr), refcount, checksum, extent.get_type()},
+ &extent
+ };
}
};
* checksum : ceph_le32[1] 4B
* size : ceph_le32[1] 4B
* meta : lba_node_meta_le_t[1] 36B
- * keys : laddr_le_t[CAPACITY] (109*16)B
- * values : lba_map_val_le_t[CAPACITY] (109*21)B
+ * keys : laddr_le_t[CAPACITY] (106*16)B
+ * values : lba_map_val_le_t[CAPACITY] (106*21)B
* = 4077B
*
* TODO: update FixedKVNodeLayout to handle the above calculation
* TODO: the above alignment probably isn't portable without further work
*/
-constexpr size_t LEAF_NODE_CAPACITY = 109;
+constexpr size_t LEAF_NODE_CAPACITY = 106;
struct LBALeafNode
: FixedKVLeafNode<
extent_types_t get_extent_type() const {
assert(is_viewable());
assert(!is_end());
+ assert(iter.get_val().type != extent_types_t::NONE);
return iter.get_val().type;
}
virtual alloc_extent_ret reserve_region(
Transaction &t,
laddr_hint_t hint,
- extent_len_t len) = 0;
+ extent_len_t len,
+ extent_types_t type) = 0;
/*
* Inserts a zero mapping at the position "pos" with
Transaction &t,
LBACursorRef cursor,
laddr_t hint,
- extent_len_t len) = 0;
+ extent_len_t len,
+ extent_types_t type) = 0;
using ref_iertr = base_iertr::extend<
crimson::ct_error::enoent>;
return ctx.tm.reserve_region(
ctx.t,
ctx.onode.get_data_hint(),
- max_object_size
+ max_object_size,
+ extent_types_t::OBJECT_DATA_BLOCK
).si_then([max_object_size=max_object_size, &object_data](auto pin) {
ceph_assert(pin.get_length() == max_object_size);
object_data.update_reserved(
).checked_to_laddr();
auto len = end.get_byte_distance<extent_len_t>(laddr);
if (len != 0) {
- zero_pos = co_await ctx.tm.reserve_region(ctx.t, std::move(zero_pos), laddr, len
+ zero_pos = co_await ctx.tm.reserve_region(
+ ctx.t, std::move(zero_pos), laddr, len,
+ extent_types_t::OBJECT_DATA_BLOCK
).handle_error_interruptible(
crimson::ct_error::enospc::assert_failure{"unexpected enospc"},
TransactionManager::get_pin_iertr::pass_further{}
reserve_extent_ret reserve_region(
Transaction &t,
laddr_hint_t hint,
- extent_len_t len) {
+ extent_len_t len,
+ extent_types_t type) {
LOG_PREFIX(TransactionManager::reserve_region);
- SUBDEBUGT(seastore_tm, "hint {}~0x{:x} ...", t, hint, len);
+ SUBDEBUGT(seastore_tm, "hint {}~0x{:x} {} ...", t, hint, len, type);
auto pin = co_await lba_manager->reserve_region(
t,
hint,
- len
+ len,
+ type
);
SUBDEBUGT(seastore_tm, "reserved {}", t, *pin);
co_return LBAMapping::create_direct(std::move(pin));
Transaction &t,
LBAMapping pos,
laddr_t hint,
- extent_len_t len) {
+ extent_len_t len,
+ extent_types_t type) {
LOG_PREFIX(TransactionManager::reserve_region);
- SUBDEBUGT(seastore_tm, "hint {}~0x{:x} ...", t, hint, len);
+ SUBDEBUGT(seastore_tm, "hint {}~0x{:x} {} ...", t, hint, len, type);
pos = co_await pos.refresh();
auto pin = co_await lba_manager->reserve_region(
t,
pos.get_effective_cursor_ref(),
hint,
- len
+ len,
+ type
);
co_return LBAMapping::create_direct(std::move(pin));
}
t,
std::move(pos),
(dst_base + cloned_to).checked_to_laddr(),
- clone_len
+ clone_len,
+ mapping.get_extent_type()
).handle_error_interruptible(
clone_iertr::pass_further{},
crimson::ct_error::assert_all{"unexpected error"}
if (!mapping.is_indirect() && mapping.is_zero_reserved()) {
SUBDEBUGT(seastore_tm, "zero reserved, mapping {}, {} remaps",
t, mapping, remaps);
+ //TODO: drop this assert
+ assert(mapping.get_extent_type() == extent_types_t::OBJECT_DATA_BLOCK);
+ auto type = mapping.get_extent_type();
std::vector<LBAMapping> ret;
auto orig_laddr = mapping.get_key();
auto pos = co_await remove(
t,
std::move(pos),
laddr,
- remap.len
+ remap.len,
+ type
).handle_error_interruptible(
remap_mappings_iertr::pass_further{},
crimson::ct_error::assert_all{"unexpected error"}
laddr_t ADDR = get_laddr_hint(0xFF * 4096);
epm->prefill_fragmented_devices();
auto t = create_transaction();
- for (int i = 0; i < 1975; i++) {
+ for (int i = 0; i < 1974; i++) {
auto extents = alloc_extents(t, (ADDR + i * 16384).checked_to_laddr(), 16384, 'a');
}
- alloc_extents_deemed_fail(t, (ADDR + 1975 * 16384).checked_to_laddr(), 16384, 'a');
+ alloc_extents_deemed_fail(t, (ADDR + 1974 * 16384).checked_to_laddr(), 16384, 'a');
check_mappings(t);
check();
submit_transaction(std::move(t));