]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd/PG: do not purge strays in premerge state
authorSage Weil <sage@redhat.com>
Fri, 10 Aug 2018 13:50:42 +0000 (08:50 -0500)
committerSage Weil <sage@redhat.com>
Fri, 7 Sep 2018 17:09:42 +0000 (12:09 -0500)
The point of premerge is to ensure that the constituent parts of the
target PG are fully clean.  If there is an intervening PG migration and
one of the halves finishes migrating before the other, one half could
get removed and the final merge could result in an incomplete PG.  In the
worst case, the two halves (let's call them A and B) could have started
out together on say [0,1,2], A moves to [3,4,5] and gets deleted from
[0,1,2], and then the final merge happens such that *all* copies of the PG
are incomplete.

We could construct a clever check that does allow removal of strays when
the sibling PG is also ready to go, but it would be complicated.  Do the
simple thing.  In reality, this would be an extremely hard case to hit
because the premerge window is generally very short.

Signed-off-by: Sage Weil <sage@redhat.com>
src/osd/PG.cc
src/osd/PG.h

index ae881ad6307d047d40288fabd5c45ae26ccfc568..4fe7efb36f5bb27e2ccf01639813f367ed5358c6 100644 (file)
@@ -2901,6 +2901,11 @@ void PG::cancel_recovery()
 
 void PG::purge_strays()
 {
+  if (is_premerge()) {
+    dout(10) << "purge_strays " << stray_set << " but premerge, doing nothing"
+            << dendl;
+    return;
+  }
   dout(10) << "purge_strays " << stray_set << dendl;
   
   bool removed = false;
index a4a5142f1bdbf7d07b28c9efb42a88ddee49bc41..dc14dfb63ba7f650bca3c38baddb4cf37ccff0e3 100644 (file)
@@ -2833,6 +2833,7 @@ protected:
     return state_test(PG_STATE_ACTIVE) || state_test(PG_STATE_PEERED);
   }
   bool is_recovering() const { return state_test(PG_STATE_RECOVERING); }
+  bool is_premerge() const { return state_test(PG_STATE_PREMERGE); }
 
   bool is_empty() const { return info.last_update == eversion_t(0,0); }