From: Sage Weil Date: Wed, 12 Sep 2018 20:02:13 +0000 (-0500) Subject: osd/PG: use last_epoch_clean from ReadyToMerge point in time for fabricated history X-Git-Tag: v14.0.1~212^2~7 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=15701e8c95b2f34d3e90bfadf91e163759b2f709;p=ceph.git osd/PG: use last_epoch_clean from ReadyToMerge point in time for fabricated history 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 --- diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index b7c6ecac52c10..cffc61739436c 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -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; diff --git a/src/osd/PG.cc b/src/osd/PG.cc index 5dc8d1dc45c97..beaf7b1743be0 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -2644,7 +2644,8 @@ void PG::finish_split_stats(const object_stat_sum_t& stats, ObjectStore::Transac } void PG::merge_from(map& 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& 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; diff --git a/src/osd/PG.h b/src/osd/PG.h index dc14dfb63ba7f..c44563ba0109b 100644 --- a/src/osd/PG.h +++ b/src/osd/PG.h @@ -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& 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);