From 3de27b25cb6104d810f7af81809a0813df6c46a4 Mon Sep 17 00:00:00 2001 From: myoungwon oh Date: Tue, 28 Jun 2022 13:42:21 +0900 Subject: [PATCH] osd: return ENOENT if pool information is invalid during tier-flush During tier-flush, OSD sends reference increase message to target OSD. At this point, sending message with invalid pool information (e.g., deleted pool) causes unexpected behavior. Therefore, this commit return ENOENT early before sending the message fixes: https://tracker.ceph.com/issues/53294 Signed-off-by: Myoungwon Oh --- src/osd/PrimaryLogPG.cc | 29 ++++++++++++++++++++++------- src/osd/PrimaryLogPG.h | 2 +- src/test/librados/tier_cxx.cc | 3 +++ 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/osd/PrimaryLogPG.cc b/src/osd/PrimaryLogPG.cc index 58a065f96dc79..d302e157d0281 100644 --- a/src/osd/PrimaryLogPG.cc +++ b/src/osd/PrimaryLogPG.cc @@ -7106,7 +7106,11 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector& ops) goto fail; } pg_t raw_pg; - get_osdmap()->object_locator_to_pg(target_name, target_oloc, raw_pg); + result = get_osdmap()->object_locator_to_pg(target_name, target_oloc, raw_pg); + if (result < 0) { + dout(5) << " pool information is invalid: " << result << dendl; + break; + } hobject_t target(target_name, target_oloc.key, target_snapid, raw_pg.ps(), raw_pg.pool(), target_oloc.nspace); @@ -7255,7 +7259,11 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector& ops) pg_t raw_pg; chunk_info_t chunk_info; - get_osdmap()->object_locator_to_pg(tgt_name, tgt_oloc, raw_pg); + result = get_osdmap()->object_locator_to_pg(tgt_name, tgt_oloc, raw_pg); + if (result < 0) { + dout(5) << " pool information is invalid: " << result << dendl; + break; + } hobject_t target(tgt_name, tgt_oloc.key, snapid_t(), raw_pg.ps(), raw_pg.pool(), tgt_oloc.nspace); @@ -10577,7 +10585,10 @@ int PrimaryLogPG::do_cdc(const object_info_t& oi, for (auto p : cdc_chunks) { bufferlist chunk; chunk.substr_of(bl, p.first, p.second); - hobject_t target = get_fpoid_from_chunk(oi.soid, chunk); + auto [ret, target] = get_fpoid_from_chunk(oi.soid, chunk); + if (ret < 0) { + return ret; + } chunks[p.first] = std::move(chunk); chunk_map[p.first] = chunk_info_t(0, p.second, target); total_length += p.second; @@ -10585,11 +10596,12 @@ int PrimaryLogPG::do_cdc(const object_info_t& oi, return total_length; } -hobject_t PrimaryLogPG::get_fpoid_from_chunk(const hobject_t soid, bufferlist& chunk) +std::pair PrimaryLogPG::get_fpoid_from_chunk( + const hobject_t soid, bufferlist& chunk) { pg_pool_t::fingerprint_t fp_algo = pool.info.get_fingerprint_type(); if (fp_algo == pg_pool_t::TYPE_FINGERPRINT_NONE) { - return hobject_t(); + return make_pair(-EINVAL, hobject_t()); } object_t fp_oid = [&fp_algo, &chunk]() -> string { switch (fp_algo) { @@ -10610,11 +10622,14 @@ hobject_t PrimaryLogPG::get_fpoid_from_chunk(const hobject_t soid, bufferlist& c oloc.pool = pool.info.get_dedup_tier(); // check if dedup_tier isn't set ceph_assert(oloc.pool > 0); - get_osdmap()->object_locator_to_pg(fp_oid, oloc, raw_pg); + int ret = get_osdmap()->object_locator_to_pg(fp_oid, oloc, raw_pg); + if (ret < 0) { + return make_pair(ret, hobject_t()); + } hobject_t target(fp_oid, oloc.key, snapid_t(), raw_pg.ps(), raw_pg.pool(), oloc.nspace); - return target; + return make_pair(0, target); } int PrimaryLogPG::finish_set_dedup(hobject_t oid, int r, ceph_tid_t tid, uint64_t offset) diff --git a/src/osd/PrimaryLogPG.h b/src/osd/PrimaryLogPG.h index 2605c992bca33..435e4169ce3fc 100644 --- a/src/osd/PrimaryLogPG.h +++ b/src/osd/PrimaryLogPG.h @@ -1459,7 +1459,7 @@ protected: int do_cdc(const object_info_t& oi, std::map& chunk_map, std::map& chunks); int start_dedup(OpRequestRef op, ObjectContextRef obc); - hobject_t get_fpoid_from_chunk(const hobject_t soid, bufferlist& chunk); + std::pair get_fpoid_from_chunk(const hobject_t soid, bufferlist& chunk); int finish_set_dedup(hobject_t oid, int r, ceph_tid_t tid, uint64_t offset); int finish_set_manifest_refcount(hobject_t oid, int r, ceph_tid_t tid, uint64_t offset); diff --git a/src/test/librados/tier_cxx.cc b/src/test/librados/tier_cxx.cc index f34accf8f1340..e8f345bd5adc9 100644 --- a/src/test/librados/tier_cxx.cc +++ b/src/test/librados/tier_cxx.cc @@ -5678,6 +5678,9 @@ TEST_F(LibRadosTwoPoolsPP, TierFlushDuringFlush) { // delete temp pool, so flushing chunk will fail ASSERT_EQ(0, s_cluster.pool_delete(temp_pool_name.c_str())); + // wait for maps to settle + cluster.wait_for_latest_osdmap(); + // flush to check if proper error is returned { ObjectReadOperation op; -- 2.39.5