From: Matan Breizman Date: Wed, 3 Aug 2022 11:26:27 +0000 (+0000) Subject: crimson/osd: whiteout removed head object with existing clones X-Git-Tag: v18.0.0~197^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=0f89eb672aacaa835e72f31fecfd4b77a6117c25;p=ceph-ci.git crimson/osd: whiteout removed head object with existing clones Signed-off-by: Matan Breizman --- diff --git a/src/crimson/os/cyanstore/cyan_store.cc b/src/crimson/os/cyanstore/cyan_store.cc index 03244150743..0126ce02f12 100644 --- a/src/crimson/os/cyanstore/cyan_store.cc +++ b/src/crimson/os/cyanstore/cyan_store.cc @@ -357,6 +357,7 @@ seastar::future<> CyanStore::do_transaction(CollectionRef ch, } break; case Transaction::OP_TOUCH: + case Transaction::OP_CREATE: { coll_t cid = i.get_cid(op->cid); ghobject_t oid = i.get_oid(op->oid); diff --git a/src/crimson/osd/ops_executer.cc b/src/crimson/osd/ops_executer.cc index 7a9064de99d..74fffa84122 100644 --- a/src/crimson/osd/ops_executer.cc +++ b/src/crimson/osd/ops_executer.cc @@ -578,9 +578,19 @@ OpsExecuter::do_execute_op(OSDOp& osd_op) return backend.setxattr(os, osd_op, txn, delta_stats); }); case CEPH_OSD_OP_DELETE: - return do_write_op([this](auto& backend, auto& os, auto& txn) { - return backend.remove(os, txn, delta_stats); + { + bool whiteout = false; + if (!obc->ssc->snapset.clones.empty() || + (snapc.snaps.size() && // there are snaps + snapc.snaps[0] > obc->ssc->snapset.seq)) { // existing obj is old + logger().debug("{} has or will have clones, will whiteout {}", + __func__, obc->obs.oi.soid); + whiteout = true; + } + return do_write_op([this, whiteout](auto& backend, auto& os, auto& txn) { + return backend.remove(os, txn, delta_stats, whiteout); }); + } case CEPH_OSD_OP_CALL: return this->do_op_call(osd_op); case CEPH_OSD_OP_STAT: @@ -815,6 +825,10 @@ const object_info_t OpsExecuter::prepare_clone( static_snap_oi.version = osd_op_params->at_version; static_snap_oi.prior_version = obc->obs.oi.version; static_snap_oi.copy_user_bits(obc->obs.oi); + if (static_snap_oi.is_whiteout()) { + // clone shouldn't be marked as whiteout + static_snap_oi.clear_flag(object_info_t::FLAG_WHITEOUT); + } if (pg->is_primary()) { // lookup_or_create diff --git a/src/crimson/osd/pg.cc b/src/crimson/osd/pg.cc index c6c3f42b9eb..30fc937cbba 100644 --- a/src/crimson/osd/pg.cc +++ b/src/crimson/osd/pg.cc @@ -1053,6 +1053,10 @@ PG::with_clone_obc(hobject_t oid, with_obc_func_t&& func) assert(!oid.is_head()); return with_head_obc(oid.get_head(), [oid, func=std::move(func), this](auto head) -> load_obc_iertr::future<> { + if (!head->obs.exists) { + logger().error("with_clone_obc: {} head doesn't exist", head->obs.oi.soid); + return load_obc_iertr::future<>{crimson::ct_error::object_corrupted::make()}; + } auto coid = resolve_oid(head->get_ro_ss(), oid); if (!coid) { logger().error("with_clone_obc: {} clone not found", coid); @@ -1067,6 +1071,7 @@ PG::with_clone_obc(hobject_t oid, with_obc_func_t&& func) logger().debug("with_clone_obc: found {} in cache", clone->get_oid()); } else { logger().debug("with_clone_obc: cache miss on {}", clone->get_oid()); + //TODO: generalize load_head_obc -> load_obc (support head/clone obc) loaded = clone->template with_promoted_lock( [clone, head, this] { return backend->load_metadata(clone->get_oid()).safe_then_interruptible( diff --git a/src/crimson/osd/pg_backend.cc b/src/crimson/osd/pg_backend.cc index 77dcc580191..bdadabb8e19 100644 --- a/src/crimson/osd/pg_backend.cc +++ b/src/crimson/osd/pg_backend.cc @@ -827,7 +827,8 @@ PGBackend::create_iertr::future<> PGBackend::create( } } maybe_create_new_object(os, txn, delta_stats); - txn.nop(); + txn.create(coll->get_cid(), + ghobject_t{os.oi.soid, ghobject_t::NO_GEN, shard}); return seastar::now(); } @@ -849,24 +850,38 @@ PGBackend::remove(ObjectState& os, ceph::os::Transaction& txn) PGBackend::remove_iertr::future<> PGBackend::remove(ObjectState& os, ceph::os::Transaction& txn, - object_stat_sum_t& delta_stats) + object_stat_sum_t& delta_stats, bool whiteout) { if (!os.exists) { return crimson::ct_error::enoent::make(); } - // todo: snapset + + if (whiteout && os.oi.is_whiteout()) { + logger().debug("{} whiteout set on {} ",__func__, os.oi.soid); + return seastar::now(); + } txn.remove(coll->get_cid(), ghobject_t{os.oi.soid, ghobject_t::NO_GEN, shard}); delta_stats.num_bytes -= os.oi.size; os.oi.size = 0; os.oi.new_object(); - os.exists = false; + + // todo: clone_overlap + if (whiteout) { + logger().debug("{} setting whiteout on {} ",__func__, os.oi.soid); + os.oi.set_flag(object_info_t::FLAG_WHITEOUT); + delta_stats.num_whiteouts++; + txn.create(coll->get_cid(), + ghobject_t{os.oi.soid, ghobject_t::NO_GEN, shard}); + return seastar::now(); + } // todo: update watchers if (os.oi.is_whiteout()) { os.oi.clear_flag(object_info_t::FLAG_WHITEOUT); delta_stats.num_whiteouts--; } delta_stats.num_objects--; + os.exists = false; return seastar::now(); } diff --git a/src/crimson/osd/pg_backend.h b/src/crimson/osd/pg_backend.h index 34ea12652af..7777b53781c 100644 --- a/src/crimson/osd/pg_backend.h +++ b/src/crimson/osd/pg_backend.h @@ -147,7 +147,8 @@ public: remove_iertr::future<> remove( ObjectState& os, ceph::os::Transaction& txn, - object_stat_sum_t& delta_stats); + object_stat_sum_t& delta_stats, + bool whiteout); interruptible_future<> remove( ObjectState& os, ceph::os::Transaction& txn);