From: myoungwon oh Date: Tue, 28 Jun 2022 04:42:21 +0000 (+0900) Subject: osd: return ENOENT if pool information is invalid during tier-flush X-Git-Tag: v16.2.11~386^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F46748%2Fhead;p=ceph.git 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 (cherry picked from 3de27b25cb6104d810f7af81809a0813df6c46a4) --- diff --git a/src/osd/PrimaryLogPG.cc b/src/osd/PrimaryLogPG.cc index c0f3f748ddca..497f280746c8 100644 --- a/src/osd/PrimaryLogPG.cc +++ b/src/osd/PrimaryLogPG.cc @@ -6972,7 +6972,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); @@ -7119,7 +7123,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); @@ -10315,19 +10323,23 @@ 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); - chunks[p.first] = move(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; } 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) { @@ -10348,11 +10360,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 9b6c017f3647..358061acbe1c 100644 --- a/src/osd/PrimaryLogPG.h +++ b/src/osd/PrimaryLogPG.h @@ -1475,7 +1475,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); friend struct C_ProxyChunkRead; diff --git a/src/test/librados/tier_cxx.cc b/src/test/librados/tier_cxx.cc index 2091e911c0a5..08ccb608213b 100644 --- a/src/test/librados/tier_cxx.cc +++ b/src/test/librados/tier_cxx.cc @@ -5473,6 +5473,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;