mirror of
https://github.com/ceph/ceph
synced 2024-12-17 17:05:42 +00:00
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 <sam.just@inktank.com>
This commit is contained in:
parent
2dd179883e
commit
07f853db39
@ -928,6 +928,7 @@ 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;
|
||||
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
|
||||
@ -935,6 +936,15 @@ 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) {
|
||||
continue;
|
||||
}
|
||||
// Disquality anyone who is incomplete (not fully backfilled)
|
||||
if (p->second.is_incomplete())
|
||||
continue;
|
||||
|
Loading…
Reference in New Issue
Block a user