]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: recover unreadable snapshots when handling manifest object 40289/head
authormyoungwon oh <ohmyoungwon@gmail.com>
Wed, 24 Feb 2021 14:16:39 +0000 (23:16 +0900)
committerSage Weil <sage@newdream.net>
Sun, 21 Mar 2021 13:23:11 +0000 (08:23 -0500)
The manifest object needs adjacent clones to increment/decrement
refcount when modifying the object. So, recovering the clones is needed
if the adjacent clones are unreadable.

Signed-off-by: Myoungwon Oh <myoungwon.oh@samsumg.com>
(cherry picked from commit b242a2c061182b724fa8016d1175f2b23e570d4b)

src/osd/PrimaryLogPG.cc
src/osd/PrimaryLogPG.h

index 4a17591cf194cb5aea82fccf0e39e98564ea18c0..24b53d6967458643d5ab93523c848c1ad690ee75 100644 (file)
@@ -2287,6 +2287,9 @@ void PrimaryLogPG::do_op(OpRequestRef& op)
   }
 
   if (obc.get() && obc->obs.exists && obc->obs.oi.has_manifest()) {
+    if (recover_adjacent_clones(obc, op)) {
+      return;
+    }
     if (maybe_handle_manifest(op,
                               write_ordered,
                               obc))
@@ -3378,6 +3381,38 @@ int PrimaryLogPG::get_manifest_ref_count(ObjectContextRef obc, std::string& fp_o
   return cnt;
 }
 
+bool PrimaryLogPG::recover_adjacent_clones(ObjectContextRef obc, OpRequestRef op)
+{
+  if (!obc->obs.oi.manifest.is_chunked() || !obc->ssc || !obc->ssc->snapset.clones.size()) {
+    return false;
+  }
+
+  const SnapSet& snapset = obc->ssc->snapset;
+  auto s = std::find(snapset.clones.begin(), snapset.clones.end(), obc->obs.oi.soid.snap);
+  auto is_unreadable_snap = [this, obc, &snapset, op](auto iter) -> bool {
+    hobject_t cid = obc->obs.oi.soid;
+    cid.snap = (iter == snapset.clones.end()) ? snapid_t(CEPH_NOSNAP) : *iter;
+    if (is_unreadable_object(cid)) {
+      dout(10) << __func__ << ": clone " << cid
+              << " is unreadable, waiting" << dendl;
+      wait_for_unreadable_object(cid, op);
+      return true;
+    }
+    return false;
+  };
+  if (s != snapset.clones.begin()) {
+    if (is_unreadable_snap(s - 1)) {
+      return true;
+    }
+  }
+  if (s != snapset.clones.end()) {
+    if (is_unreadable_snap(s + 1)) {
+      return true;
+    }
+  }
+  return false;
+}
+
 ObjectContextRef PrimaryLogPG::get_prev_clone_obc(ObjectContextRef obc)
 {
   auto s = std::find(obc->ssc->snapset.clones.begin(), obc->ssc->snapset.clones.end(),
index 134b3ba1a937a7a40b6bf7b8cd94fb118e8606a5..1a8f8560870b2162029141a2428326b37f0b1795 100644 (file)
@@ -1467,6 +1467,7 @@ protected:
   void dec_refcount(const hobject_t& soid, const object_ref_delta_t& refs);
   void dec_refcount_by_dirty(OpContext* ctx);
   ObjectContextRef get_prev_clone_obc(ObjectContextRef obc);
+  bool recover_adjacent_clones(ObjectContextRef obc, OpRequestRef op);
   void get_adjacent_clones(ObjectContextRef src_obc, 
                           ObjectContextRef& _l, ObjectContextRef& _g);
   bool inc_refcount_by_set(OpContext* ctx, object_manifest_t& tgt,