From: Samuel Just Date: Sat, 16 Jun 2012 00:09:42 +0000 (-0700) Subject: PG: best_info must have a last_epoch_started as high as any other info X-Git-Tag: v0.48argonaut~45 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=51fcef2465f1b6c492187aede4178f10b0963dce;p=ceph.git PG: best_info must have a last_epoch_started as high as any other info We disregard incomplete infos during find_best_info, but we can't an info with a last_epoch_started less that of the incomplete info. This should avoid cases like #2462. In that case, it appears that a peer with empty info/log was chosen as authoritative even though there was a non-empty incomplete peer. Signed-off-by: Samuel Just --- diff --git a/src/osd/PG.cc b/src/osd/PG.cc index abf33d204ba..2e6013edf71 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -928,6 +928,7 @@ void PG::clear_primary_state() */ map::const_iterator PG::find_best_info(const map &infos) const { + epoch_t last_epoch_started = 0; map::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 @@ -935,6 +936,15 @@ map::const_iterator PG::find_best_info(const map for (map::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) { + continue; + } // Disquality anyone who is incomplete (not fully backfilled) if (p->second.is_incomplete()) continue;