]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd/PG: use last_epoch_clean from ReadyToMerge point in time for fabricated history
authorSage Weil <sage@redhat.com>
Wed, 12 Sep 2018 20:02:13 +0000 (15:02 -0500)
committerSage Weil <sage@redhat.com>
Thu, 20 Sep 2018 13:35:15 +0000 (08:35 -0500)
If we are fabricating the pg history values, we need something that is
reasonably valid, but that won't screw up peering of the PG by indicating
that the PG has peered at some point later than when it really has.
Otherwise we can end up in a situation where everyone thinks there is a
newer pg info out there that doesn't actually exist, and the PG will end
up as incomplete.

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

index b7c6ecac52c104769d7aeb7f918255d73e612bd3..cffc61739436c70f656efeb7749c878dbdae2b41 100644 (file)
@@ -8212,7 +8212,10 @@ bool OSD::advance_pg(
            unsigned new_pg_num = nextmap->get_pg_num(pg->pg_id.pool());
            unsigned split_bits = pg->pg_id.get_split_bits(new_pg_num);
            dout(1) << __func__ << " merging " << pg->pg_id << dendl;
-           pg->merge_from(sources, rctx, split_bits);
+           pg->merge_from(
+             sources, rctx, split_bits,
+             nextmap->get_pg_pool(
+               pg->pg_id.pool())->get_pg_num_dec_last_epoch_clean());
            pg->pg_slot->waiting_for_merge_epoch = 0;
          } else {
            dout(20) << __func__ << " not ready to merge yet" << dendl;
index 5dc8d1dc45c9727c543e7effe917f282d5478780..beaf7b1743be02e8ec9a3fc09cb1033b5da2e290 100644 (file)
@@ -2644,7 +2644,8 @@ void PG::finish_split_stats(const object_stat_sum_t& stats, ObjectStore::Transac
 }
 
 void PG::merge_from(map<spg_t,PGRef>& sources, RecoveryCtx *rctx,
-                   unsigned split_bits)
+                   unsigned split_bits,
+                   epoch_t dec_last_epoch_clean)
 {
   dout(10) << __func__ << " from " << sources << " split_bits " << split_bits
           << dendl;
@@ -2725,8 +2726,11 @@ void PG::merge_from(map<spg_t,PGRef>& sources, RecoveryCtx *rctx,
   // make sure we have a meaningful last_epoch_started/clean (if we were a
   // placeholder)
   if (info.last_epoch_started == 0) {
+    // we use the pg_num_dec_last_epoch_clean we got from the caller, which is
+    // the epoch that was clean according to the target pg whe it requested
+    // the mon decrement pg_num.
     info.history.last_epoch_started =
-      info.history.last_epoch_clean = past_intervals.get_bounds().first;
+      info.history.last_epoch_clean = dec_last_epoch_clean;
     dout(10) << __func__
             << " set last_epoch_started/clean based on past intervals"
             << dendl;
index dc14dfb63ba7f650bca3c38baddb4cf37ccff0e3..c44563ba0109ba214c1b3ffc7c4888e70ac6a83a 100644 (file)
@@ -399,7 +399,8 @@ public:
     ObjectStore::Transaction *t) = 0;
   void split_into(pg_t child_pgid, PG *child, unsigned split_bits);
   void merge_from(map<spg_t,PGRef>& sources, RecoveryCtx *rctx,
-                 unsigned split_bits);
+                 unsigned split_bits,
+                 epoch_t dec_last_epoch_clean);
   void finish_split_stats(const object_stat_sum_t& stats, ObjectStore::Transaction *t);
 
   void scrub(epoch_t queued, ThreadPool::TPHandle &handle);