version_t get_last_user_version() const;
+ bool has_cloning_ctx() const {
+ return cloning_ctx != nullptr;
+ }
+
+ const hobject_t& get_cloning_coid() const {
+ ceph_assert(has_cloning_ctx());
+ return cloning_ctx->coid;
+ }
+
+ void reset_cloning_ctx() {
+ cloning_ctx.reset();
+ }
+
ObjectContextRef prepare_clone(
const hobject_t& coid,
const ObjectState& initial_obs);
{
LOG_PREFIX(PG::run_executer);
auto rollbacker = ox.create_rollbacker(
- [obc_data = duplicate_obc_data(obc)](auto &obc) mutable {
+ [FNAME, obc_data = duplicate_obc_data(obc), &ox, this](auto &obc) mutable {
+ // First, revert the OBC state
obc->update_from(obc_data);
+ // Then clean up any prepared clone OBCs
+ if (ox.has_cloning_ctx()) {
+ const auto coid = ox.get_cloning_coid();
+ DEBUGDPP("cleaning up clone OBC for {} reqid={}",
+ FNAME, coid, ox.get_message().get_reqid());
+ // Use single-key clear by passing [coid, coid] to avoid impacting other clones
+ this->obc_registry.clear_range(coid, coid);
+ // Reset the cloning context directly
+ ox.reset_cloning_ctx();
+ }
});
auto rollback_on_error = seastar::defer([&rollbacker] {
rollbacker.rollback_obc_if_modified();