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();
+ if (!is_retired_placeholder_type(type)) {
+ 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)};
}
};
assert(!is_end());
return val->len;
}
+
+ extent_types_t get_extent_type() const {
+ assert(val->type != extent_types_t::NONE);
+ return val->type;
+ }
};
struct LBACursor : BtreeCursor<laddr_t, lba::lba_map_val_t> {
if (cursor.is_end()) {
return out << "END)";
}
- return out << "," << cursor.key
+ return out << cursor.key
<< "~" << *cursor.val
<< ")";
}
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](auto &ret) {
Transaction &t,
LBAMapping pos,
laddr_t addr,
- extent_len_t len)
+ extent_len_t len,
+ extent_types_t type)
{
LOG_PREFIX(BtreeLBAManager::reserve_region);
DEBUGT("{} {}~{}", t, pos, addr, len);
return with_btree<LBABtree>(
cache,
c,
- [pos=std::move(pos), c, addr, len](auto &btree) mutable {
+ [pos=std::move(pos), c, addr, len, type](auto &btree) mutable {
auto &cursor = pos.get_effective_cursor();
auto iter = btree.make_partial_iter(c, cursor);
- lba_map_val_t val{
- len,
- pladdr_t{P_ADDR_ZERO},
- EXTENT_DEFAULT_REF_COUNT,
- 0,
- extent_types_t::NONE};
+ lba_map_val_t val{len, pladdr_t{P_ADDR_ZERO}, EXTENT_DEFAULT_REF_COUNT, 0, type};
return btree.insert(c, iter, addr, val
).si_then([c](auto p) {
auto &[iter, inserted] = p;
btree.make_partial_iter(c, cursor),
state.laddr,
lba_map_val_t{
- state.len,
- pladdr_t{inter_key.get_local_clone_id()},
- EXTENT_DEFAULT_REF_COUNT,
- 0,
- extent_types_t::NONE});
+ state.len, pladdr_t{inter_key.get_local_clone_id()},
+ EXTENT_DEFAULT_REF_COUNT, 0, state.mapping.get_extent_type()});
}).si_then([c, &state](auto p) {
auto &[iter, inserted] = p;
auto &leaf_node = *iter.get_leaf_node();
auto old_key = mapping.get_key();
auto new_key = (old_key + remap.offset).checked_to_laddr();
val.len = remap.len;
+ val.type = mapping.get_extent_type();
if (pladdr.is_laddr()) {
val.pladdr = pladdr;
} else {
Transaction &t,
LBAMapping 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)};
return seastar::do_with(
std::move(alloc_infos),
[&t, hint, this](auto &alloc_infos) {
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<
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,
LBAMapping pos,
laddr_t hint,
- extent_len_t len) = 0;
+ extent_len_t len,
+ extent_types_t type) = 0;
struct mapping_update_result_t {
laddr_t key;
extent_len_t>(get_intermediate_key());
}
+ extent_types_t get_extent_type() const {
+ if (direct_cursor && indirect_cursor) {
+ assert(direct_cursor->get_extent_type()
+ == indirect_cursor->get_extent_type());
+ }
+ if (direct_cursor) {
+ return direct_cursor->get_extent_type();
+ } else if (indirect_cursor) {
+ return indirect_cursor->get_extent_type();
+ } else {
+ ceph_abort("invalid LBAMapping");
+ return extent_types_t::NONE;
+ }
+ }
+
get_child_ret_t<lba::LBALeafNode, LogicalChildNode>
get_logical_extent(Transaction &t) const;
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(
(data.tailbl ? ctx.tm.get_block_size() : 0)
).checked_to_laddr();
auto len = end.get_byte_distance<extent_len_t>(laddr);
- return ctx.tm.reserve_region(ctx.t, std::move(zero_pos), laddr, len);
+ return ctx.tm.reserve_region(
+ ctx.t, std::move(zero_pos), laddr, len,
+ extent_types_t::OBJECT_DATA_BLOCK);
}).si_then([](auto zero_pos) {
return std::make_optional<LBAMapping>(std::move(zero_pos));
}).handle_error_interruptible(
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);
return lba_manager->reserve_region(
t,
hint,
- len
+ len,
+ type
).si_then([FNAME, &t](auto pin) {
SUBDEBUGT(seastore_tm, "reserved {}", t, pin);
return 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);
return pos.refresh(
- ).si_then([FNAME, this, &t, hint, len](auto pos) {
+ ).si_then([FNAME, this, &t, hint, len, type](auto pos) {
return lba_manager->reserve_region(
t,
std::move(pos),
hint,
- len
+ len,
+ type
).si_then([FNAME, &t](auto pin) {
SUBDEBUGT(seastore_tm, "reserved {}", t, pin);
return 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"}
t,
std::move(pos),
laddr,
- remap.len
+ remap.len,
+ extent_types_t::OBJECT_DATA_BLOCK
).si_then([&mappings](auto new_mapping) {
mappings.emplace_back(new_mapping);
return new_mapping.next();
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));