]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
PG: improve find_best_info
authorSamuel Just <sam.just@inktank.com>
Tue, 19 Jun 2012 16:11:57 +0000 (09:11 -0700)
committerSamuel Just <sam.just@inktank.com>
Tue, 19 Jun 2012 17:49:48 +0000 (10:49 -0700)
07f853db3982e68b952a337cf91cbf7ec0709de9 is actually too conservative,
it suffices to find any info with a last_update of at least the least
last_update from the last period to go active.  An info from a previous
interval is acceptable if the last interval never reported a commited
operation and thus still has the same last_update.

Signed-off-by: Samuel Just <sam.just@inktank.com>
Reviewed-by: Sage Weil <sage@inktank.com>
src/osd/PG.cc
src/osd/osd_types.h

index 1b97618ee3c71620ad2dfb6c702068f1283e36fc..a63ab28779c0e6c7d7cd7f9547e52ae8dec1a55a 100644 (file)
@@ -928,7 +928,22 @@ void PG::clear_primary_state()
  */
 map<int, pg_info_t>::const_iterator PG::find_best_info(const map<int, pg_info_t> &infos) const
 {
-  epoch_t last_epoch_started = 0;
+  eversion_t min_last_update_acceptable = eversion_t::max();
+  epoch_t max_last_epoch_started_found = 0;
+  for (map<int, pg_info_t>::const_iterator i = infos.begin();
+       i != infos.end();
+       ++i) {
+    if (max_last_epoch_started_found < i->second.history.last_epoch_started) {
+      min_last_update_acceptable = eversion_t::max();
+      max_last_epoch_started_found = i->second.history.last_epoch_started;
+    }
+    if (max_last_epoch_started_found == i->second.history.last_epoch_started) {
+      if (min_last_update_acceptable > i->second.last_update)
+       min_last_update_acceptable = i->second.last_update;
+    }
+  }
+  assert(min_last_update_acceptable != eversion_t::max());
+
   map<int, pg_info_t>::const_iterator best = infos.end();
   // find osd with newest last_update.  if there are multiples, prefer
   //  - a longer tail, if it brings another peer into log contiguity
@@ -936,15 +951,9 @@ map<int, pg_info_t>::const_iterator PG::find_best_info(const map<int, pg_info_t>
   for (map<int, pg_info_t>::const_iterator p = infos.begin();
        p != infos.end();
        ++p) {
-    // Only consider peers with the most recent last_epoch_started found
-    if (p->second.history.last_epoch_started > last_epoch_started) {
-      last_epoch_started = p->second.history.last_epoch_started;
-      if (best != infos.end() &&
-         last_epoch_started > best->second.history.last_epoch_started)
-       best = infos.end();
-    } else if (p->second.history.last_epoch_started < last_epoch_started) {
+    // Only consider peers with last_update >= min_last_update_acceptable
+    if (p->second.last_update < min_last_update_acceptable)
       continue;
-    }
     // Disquality anyone who is incomplete (not fully backfilled)
     if (p->second.is_incomplete())
       continue;
index 9cd79414a81d3d146f21ae16893c972cf3752171..8d11aea2e30e700a49b376f1c9ee9907421bc188 100644 (file)
@@ -417,6 +417,13 @@ public:
 
   eversion_t(bufferlist& bl) : __pad(0) { decode(bl); }
 
+  static eversion_t max() {
+    eversion_t max;
+    max.version -= 1;
+    max.epoch -= 1;
+    return max;
+  }
+
   operator ceph_eversion() {
     ceph_eversion c;
     c.epoch = epoch;