]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: return ENOENT if pool information is invalid during tier-flush 46866/head
authormyoungwon oh <ohmyoungwon@gmail.com>
Tue, 28 Jun 2022 04:42:21 +0000 (13:42 +0900)
committermyoungwon oh <ohmyoungwon@gmail.com>
Fri, 15 Jul 2022 12:38:26 +0000 (21:38 +0900)
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 <myoungwon.oh@samsung.com>
src/osd/PrimaryLogPG.cc
src/osd/PrimaryLogPG.h
src/test/librados/tier_cxx.cc

index 58a065f96dc79352aa10eda352884c6340b5af07..d302e157d0281454e5227ed4496a7836a706651b 100644 (file)
@@ -7106,7 +7106,11 @@ int PrimaryLogPG::do_osd_ops(OpContext *ctx, vector<OSDOp>& 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<OSDOp>& 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<int, hobject_t> 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)
index 2605c992bca332f6939ca0aed1a5e4cd4bd0b83b..435e4169ce3fcac5c99c0e47d2216faa96433000 100644 (file)
@@ -1459,7 +1459,7 @@ protected:
   int do_cdc(const object_info_t& oi, std::map<uint64_t, chunk_info_t>& chunk_map,
             std::map<uint64_t, bufferlist>& chunks);
   int start_dedup(OpRequestRef op, ObjectContextRef obc);
-  hobject_t get_fpoid_from_chunk(const hobject_t soid, bufferlist& chunk);
+  std::pair<int, hobject_t> 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);
 
index f34accf8f1340612db5e5ca7c176356c5ae509e9..e8f345bd5adc93587c933cd67823fded55304ad8 100644 (file)
@@ -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;