Skip to content

Commit b32194a

Browse files
committed
crimson/osd: fix assertion fail in prepare_clone
Ops like rbd.assert_snapc_seq can return -ERANGE, but we were preparing clones in OpsExecuter constructor before guard evaluation. On retry with sparse_copyup, this led to ceph_assert(!existed) in prepare_clone() due to the pre-created clone OBC. This adds precise OBC invalidation during rollback using single key clear. Fixes: https://tracker.ceph.com/issues/72705 Fixes: https://tracker.ceph.com/issues/72709 Fixes: https://tracker.ceph.com/issues/72041 Fixes: https://tracker.ceph.com/issues/72650 Signed-off-by: Kautilya Tripathi <[email protected]>
1 parent 61cdd26 commit b32194a

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

src/crimson/osd/ops_executer.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,19 @@ class OpsExecuter {
450450

451451
version_t get_last_user_version() const;
452452

453+
bool has_cloning_ctx() const {
454+
return cloning_ctx != nullptr;
455+
}
456+
457+
const hobject_t& get_cloning_coid() const {
458+
ceph_assert(has_cloning_ctx());
459+
return cloning_ctx->coid;
460+
}
461+
462+
void reset_cloning_ctx() {
463+
cloning_ctx.reset();
464+
}
465+
453466
ObjectContextRef prepare_clone(
454467
const hobject_t& coid,
455468
const ObjectState& initial_obs);

src/crimson/osd/pg.cc

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1155,8 +1155,19 @@ PG::run_executer_fut PG::run_executer(
11551155
{
11561156
LOG_PREFIX(PG::run_executer);
11571157
auto rollbacker = ox.create_rollbacker(
1158-
[obc_data = duplicate_obc_data(obc)](auto &obc) mutable {
1158+
[FNAME, obc_data = duplicate_obc_data(obc), &ox, this](auto &obc) mutable {
1159+
// First, revert the OBC state
11591160
obc->update_from(obc_data);
1161+
// Then clean up any prepared clone OBCs
1162+
if (ox.has_cloning_ctx()) {
1163+
const auto coid = ox.get_cloning_coid();
1164+
DEBUGDPP("cleaning up clone OBC for {} reqid={}",
1165+
FNAME, coid, ox.get_message().get_reqid());
1166+
// Use single-key clear by passing [coid, coid] to avoid impacting other clones
1167+
this->obc_registry.clear_range(coid, coid);
1168+
// Reset the cloning context directly
1169+
ox.reset_cloning_ctx();
1170+
}
11601171
});
11611172
auto rollback_on_error = seastar::defer([&rollbacker] {
11621173
rollbacker.rollback_obc_if_modified();

0 commit comments

Comments
 (0)