auto &lextent = static_cast<LogicalChildNode&>(extent);
auto &prior = *extent.prior_instance;
for (auto &item : prior.read_transactions) {
- item.t->maybe_sync_copied_lba_key(
- lextent.get_laddr(), lextent.get_paddr());
+ switch (t.get_src()) {
+ case transaction_type_t::PROMOTE:
+ {
+ auto &shadow = *lextent.get_shadow();
+ item.t->maybe_sync_copied_lba_key(
+ lextent.get_laddr(),
+ lextent.get_paddr(),
+ shadow.get_paddr());
+ break;
+ }
+ case transaction_type_t::DEMOTE:
+ item.t->maybe_sync_copied_lba_key(
+ lextent.get_laddr(),
+ lextent.get_paddr(),
+ P_ADDR_NULL);
+ break;
+ default:
+ item.t->maybe_sync_copied_lba_key(
+ lextent.get_laddr(),
+ lextent.get_paddr(),
+ std::nullopt);
+ break;
+ }
}
}
void BtreeLBAManager::update_paddr_sync(
Transaction &t,
laddr_t laddr,
- paddr_t paddr)
+ paddr_t paddr,
+ std::optional<paddr_t> shadow)
{
LOG_PREFIX(BtreeLBAManager::update_paddr_sync);
DEBUGT("laddr={}, paddr={}", t, laddr, paddr);
ceph_assert(child->is_exist_clean());
auto cursor = iter.get_cursor(c);
assert(cursor->get_laddr() == laddr);
+ paddr_t shadow_paddr;
+ if (shadow) {
+ // the committing txn changed the shadow
+ // to *shadow
+ shadow_paddr = *shadow;
+ } else if (cursor->has_shadow_paddr()) {
+ // shadow is preserved by the committer,
+ // and the copy inherited one, so the source
+ // was promoted when it's copied
+ shadow_paddr = cursor->get_shadow_paddr();
+ } else {
+ // shadow is preserved, and nothing is
+ // inherited: not currently promoted
+ shadow_paddr = P_ADDR_NULL;
+ }
btree.update(
c,
std::move(iter),
lba_map_val_t{
cursor->get_length(),
pladdr_t{std::move(paddr)},
+ shadow_paddr,
cursor->get_refcount(),
cursor->get_checksum(),
cursor->get_extent_type()},
c.trans.new_lba_key_copied(
ret.src->get_key(),
dest_laddr,
- [this, c](laddr_t laddr, paddr_t paddr) {
- update_paddr_sync(c.trans, laddr, paddr);
+ [this, c](laddr_t laddr, paddr_t paddr, std::optional<paddr_t> shadow) {
+ update_paddr_sync(c.trans, laddr, paddr, shadow);
});
auto [niter, inserted] = co_await btree.copy(
c,
bool force_rewrite_conflict = false;
using update_copied_lba_key_func_t =
- std::function<void (laddr_t, paddr_t)>;
+ std::function<void (laddr_t, paddr_t, std::optional<paddr_t>)>;
void new_lba_key_copied(
laddr_t src,
laddr_t dest,
update_copied_lba_key = std::move(func);
}
}
- void maybe_sync_copied_lba_key(laddr_t laddr, paddr_t paddr) {
+ void maybe_sync_copied_lba_key(
+ laddr_t laddr, paddr_t paddr, std::optional<paddr_t> shadow) {
if (likely(copied_lba_keys.empty())) {
return;
}
return;
}
laddr_t key = it->second;
- update_copied_lba_key(key, paddr);
+ update_copied_lba_key(key, paddr, shadow);
}
RootBlockRef peek_root() {
return root;