From: Xuehan Xu Date: Tue, 24 Feb 2026 07:35:58 +0000 (+0800) Subject: crimson/os/seastore/lba: TRIM/CLEANER trans to adjust deltas of X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=6ac83c9fa78435a3406ce13482b487cab40a2553;p=ceph.git crimson/os/seastore/lba: TRIM/CLEANER trans to adjust deltas of LBALeafNodes when committing them. This is to deal with the following scenario: 1. A client transaction modifies the value of the LBALeafNode, but not the pladdr but other field; 2. A TRIM/CLEANER transaction modifies the pladdr for the same laddr_t concurrently In the old approach, the client trans may override the pladdr with the outdated value after the TRIM/CLEANER transaction commits Signed-off-by: Xuehan Xu --- diff --git a/src/crimson/common/fixed_kv_node_layout.h b/src/crimson/common/fixed_kv_node_layout.h index 7adce7158b3..a4aa8efd129 100644 --- a/src/crimson/common/fixed_kv_node_layout.h +++ b/src/crimson/common/fixed_kv_node_layout.h @@ -310,6 +310,12 @@ public: void clear() { buffer.clear(); } + template + void for_each(Func &&f) { + for (auto &i : buffer) { + std::invoke(std::forward(f), i); + } + } }; void journal_insert( diff --git a/src/crimson/os/seastore/cached_extent.cc b/src/crimson/os/seastore/cached_extent.cc index d5abf2e0853..06b64e49da5 100644 --- a/src/crimson/os/seastore/cached_extent.cc +++ b/src/crimson/os/seastore/cached_extent.cc @@ -434,12 +434,37 @@ void ExtentCommitter::_share_prior_data_to_mutations() { ceph_assert(is_lba_backref_node(extent.get_type())); auto &prior = *extent.prior_instance; for (auto &mext : prior.mutation_pending_extents) { - auto &mextent = static_cast(mext); - TRACE("{} -> {}", extent, mextent); - extent.get_bptr().copy_out( - 0, extent.get_length(), mextent.get_bptr().c_str()); - mextent.on_data_commit(); - mextent.reapply_delta(); + if (extent.get_type() == extent_types_t::LADDR_LEAF) { + // LBA leaf mappings contains other fields than just pladdr, which + // may also be modified. In this case, we can just overwrite the + // whole contents of the leaf node and reapply deltas like what + // we do for internal nodes. + auto &mextent = static_cast(mext); + auto &me = static_cast(extent); + TRACE("{} -> {}", me, mextent); + auto iter = me.begin(); + auto merged = me.merge_content_to(t, mextent, iter); + mextent.adjust_delta([&](auto &buf) { + if (buf.op == lba::LBALeafNode::delta_t::op_t::UPDATE || + // only remapping extents can create a delta with op + // INSERT and the corresponding mapping in "merged" + buf.op == lba::LBALeafNode::delta_t::op_t::INSERT) { + auto it = merged.find(buf.key); + if (it != merged.end()) { + TRACE("{} -> {}, {} -> {}", + me, mextent, (pladdr_t)buf.val.pladdr, it->second); + buf.val.pladdr = pladdr_le_t(it->second); + } + } + }); + } else { + auto &mextent = static_cast(mext); + TRACE("{} -> {}", extent, mextent); + extent.get_bptr().copy_out( + 0, extent.get_length(), mextent.get_bptr().c_str()); + mextent.on_data_commit(); + mextent.reapply_delta(); + } } } diff --git a/src/crimson/os/seastore/lba/lba_btree_node.h b/src/crimson/os/seastore/lba/lba_btree_node.h index b6831f6a210..8f6a04f2aed 100644 --- a/src/crimson/os/seastore/lba/lba_btree_node.h +++ b/src/crimson/os/seastore/lba/lba_btree_node.h @@ -288,47 +288,96 @@ struct LBALeafNode std::ostream &print_detail(std::ostream &out) const final; - template