* checksum : ceph_le32[1] 4B
* size : ceph_le32[1] 4B
* meta : backref_node_meta_le_t[1] 20B
- * keys : paddr_le_t[CAPACITY] (193*8)B
- * values : backref_map_val_le_t[CAPACITY] (193*13)B
- * = 4081B
+ * keys : paddr_le_t[CAPACITY] (140*8)B
+ * values : backref_map_val_le_t[CAPACITY] (140*21)B
+ * = 4088B
*
* 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 = 193;
+constexpr size_t LEAF_NODE_CAPACITY = 140;
using BackrefNode = FixedKVNode<paddr_t>;
laddr_t get_intermediate_key() const {
assert(is_indirect());
assert(!is_end());
- return val->pladdr.get_laddr();
+ return val->pladdr.build_laddr(key);
}
checksum_t get_checksum() const {
assert(!is_end());
auto iter = btree.make_partial_iter(c, cursor);
lba_map_val_t val{
len,
- P_ADDR_ZERO,
+ pladdr_t{P_ADDR_ZERO},
EXTENT_DEFAULT_REF_COUNT,
0,
extent_types_t::NONE};
ext->get_laddr(),
lba_map_val_t{
ext->get_length(),
- ext->get_paddr(),
+ pladdr_t{ext->get_paddr()},
EXTENT_DEFAULT_REF_COUNT,
ext->get_last_committed_crc(),
ext->get_type()}
? state.mapping.get_intermediate_key()
: state.mapping.get_key();
inter_key = (inter_key + state.offset).checked_to_laddr();
+ assert(inter_key.get_clone_prefix() != state.laddr.get_clone_prefix());
return btree.insert(
c,
btree.make_partial_iter(c, cursor),
state.laddr,
lba_map_val_t{
state.len,
- inter_key,
+ pladdr_t{inter_key.get_local_clone_id()},
EXTENT_DEFAULT_REF_COUNT,
0,
extent_types_t::NONE});
pos.get_val().type);
ceph_assert(pos.get_val().len > 0 &&
pos.get_val().len % block_size == 0);
- ceph_assert(pos.get_val().pladdr != L_ADDR_NULL);
+ ceph_assert(pos.get_val().pladdr != pladdr_t{LOCAL_CLONE_ID_NULL});
scan_visitor(
pos.get_val().pladdr.get_paddr(),
pos.get_val().len,
auto new_key = (old_key + remap.offset).checked_to_laddr();
val.len = remap.len;
if (pladdr.is_laddr()) {
- auto laddr = pladdr.get_laddr();
- val.pladdr = (laddr + remap.offset).checked_to_laddr();
+ val.pladdr = pladdr;
} else {
auto paddr = pladdr.get_paddr();
val.pladdr = paddr + remap.offset;
laddr,
{
len,
- pladdr_t(intermediate_key),
+ pladdr_t(intermediate_key.get_local_clone_id()),
EXTENT_DEFAULT_REF_COUNT,
0, // crc will only be used and checked with LBA direct mappings
// also see pin_to_extent(_by_type)
* Layout (4KiB):
* checksum : ceph_le32[1] 4B
* size : ceph_le32[1] 4B
- * meta : lba_node_meta_le_t[1] 20B
- * keys : laddr_le_t[CAPACITY] (254*8)B
- * values : paddr_le_t[CAPACITY] (254*8)B
- * = 4092B
+ * meta : lba_node_meta_le_t[1] 36B
+ * keys : laddr_le_t[CAPACITY] (168*16)B
+ * values : paddr_le_t[CAPACITY] (168*8)B
+ * = 4076B
* TODO: make the above capacity calculation part of FixedKVNodeLayout
* TODO: the above alignment probably isn't portable without further work
*/
-constexpr size_t INTERNAL_NODE_CAPACITY = 254;
+constexpr size_t INTERNAL_NODE_CAPACITY = 168;
struct LBAInternalNode
: FixedKVInternalNode<
INTERNAL_NODE_CAPACITY,
* Layout (4KiB):
* checksum : ceph_le32[1] 4B
* size : ceph_le32[1] 4B
- * meta : lba_node_meta_le_t[1] 20B
- * keys : laddr_le_t[CAPACITY] (140*8)B
- * values : lba_map_val_le_t[CAPACITY] (140*21)B
- * = 4088B
+ * 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
+ * = 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 = 135;
+constexpr size_t LEAF_NODE_CAPACITY = 109;
struct LBALeafNode
: FixedKVLeafNode<
std::ostream &operator<<(std::ostream &out, const pladdr_t &pladdr)
{
+ out << "pladdr(";
if (pladdr.is_laddr()) {
- return out << pladdr.get_laddr();
+ // pladdr(local_clone_id=0x...)
+ out << "local_clone_id=0x" << std::hex
+ << pladdr.get_local_clone_id() << std::dec;
} else {
- return out << pladdr.get_paddr();
+ // pladdr(paddr<...>)
+ out << pladdr.get_paddr();
}
+ return out << ")";
}
std::ostream &operator<<(std::ostream &out, const paddr_t &rhs)
bool operator==(const laddr_le_t&) const = default;
};
+/**
+ * pladdr_t
+ *
+ * The value of LBA tree leaf node entries, stores either the physical address
+ * of the logical extent, or the value of local_clone_id field of the intermediate
+ * key which points to the physical lba mapping.
+ */
struct pladdr_t {
- std::variant<laddr_t, paddr_t> pladdr;
+ std::variant<local_clone_id_t, paddr_t> pladdr;
pladdr_t() = default;
- pladdr_t(const pladdr_t &) noexcept = default;
- explicit pladdr_t(laddr_t laddr)
- : pladdr(laddr) {}
+ pladdr_t(const pladdr_t &) = default;
+ explicit pladdr_t(local_clone_id_t id)
+ : pladdr(id) {}
constexpr explicit pladdr_t(paddr_t paddr)
: pladdr(paddr) {}
return *this;
}
- pladdr_t& operator=(laddr_t laddr) {
- pladdr = laddr;
+ pladdr_t& operator=(local_clone_id_t id) {
+ pladdr = id;
return *this;
}
return paddr_t(std::get<1>(pladdr));
}
- laddr_t get_laddr() const {
+ local_clone_id_t get_local_clone_id() const {
assert(pladdr.index() == 0);
- return laddr_t(std::get<0>(pladdr));
+ return std::get<0>(pladdr);
}
+ // The corresponding lba key with stored local clone id is the real
+ // intermediate key.
+ laddr_t build_laddr(laddr_t key) const {
+ return key.with_local_clone_id(get_local_clone_id());
+ }
};
constexpr pladdr_t PL_ADDR_NULL = pladdr_t(P_ADDR_NULL);
};
struct __attribute__((packed)) pladdr_le_t {
- ceph_le64 pladdr = ceph_le64(0);
- addr_type_t addr_type = addr_type_t::MAX;
+ ceph_le64 addr;
+ addr_type_t addr_type;
- pladdr_le_t() = default;
+ pladdr_le_t() : pladdr_le_t(PL_ADDR_NULL) {}
pladdr_le_t(const pladdr_le_t &) = default;
explicit pladdr_le_t(const pladdr_t &addr)
- : pladdr(
- ceph_le64(
- addr.is_laddr() ?
- std::get<0>(addr.pladdr).value :
- std::get<1>(addr.pladdr).internal_paddr)),
- addr_type(
- addr.is_laddr() ?
- addr_type_t::LADDR :
- addr_type_t::PADDR)
+ : addr(ceph_le64(addr.is_laddr()
+ ? addr.get_local_clone_id()
+ : addr.get_paddr().internal_paddr)),
+ addr_type(addr.is_laddr()
+ ? addr_type_t::LADDR
+ : addr_type_t::PADDR)
{}
operator pladdr_t() const {
if (addr_type == addr_type_t::LADDR) {
- return pladdr_t(laddr_t(pladdr));
+ return pladdr_t(static_cast<local_clone_id_t>(addr));
} else {
assert(addr_type == addr_type_t::PADDR);
- return pladdr_t(paddr_t(pladdr));
+ return pladdr_t(paddr_t(addr));
}
}
};
laddr_t ADDR = get_laddr_hint(0xFF * 4096);
epm->prefill_fragmented_devices();
auto t = create_transaction();
- for (int i = 0; i < 1958; i++) {
+ for (int i = 0; i < 1975; i++) {
auto extents = alloc_extents(t, (ADDR + i * 16384).checked_to_laddr(), 16384, 'a');
}
- alloc_extents_deemed_fail(t, (ADDR + 1958 * 16384).checked_to_laddr(), 16384, 'a');
+ alloc_extents_deemed_fail(t, (ADDR + 1975 * 16384).checked_to_laddr(), 16384, 'a');
check_mappings(t);
check();
submit_transaction(std::move(t));