if (backlog && s < bottom)
s = bottom;
- assert(complete_to == log.end() &&
- requested_to == log.end());
+ assert(complete_to == log.end());
while (!log.empty()) {
Entry &e = *log.begin();
if (e.version > s) break;
- assert(complete_to != log.begin());
- assert(requested_to != log.begin());
-
// remove from index,
unindex(e);
}
-void PG::init_recovery_pointers()
-{
- dout(10) << "init_recovery_pointers" << dendl;
- log.complete_to = log.log.begin();
- while (log.complete_to->version < info.last_complete)
- log.complete_to++;
- assert(log.complete_to != log.log.end());
-
- if (is_primary())
- log.requested_to = log.complete_to;
-}
-
void PG::activate(ObjectStore::Transaction& t,
map<int, MOSDPGInfo*> *activator_map)
{
log.reset_recovery_pointers();
} else {
dout(10) << "activate - not complete, " << missing << dendl;
-
- init_recovery_pointers();
-
+ log.complete_to = log.log.begin();
+ while (log.complete_to->version < info.last_complete)
+ log.complete_to++;
+ assert(log.complete_to != log.log.end());
+ log.last_requested = object_t();
dout(10) << "activate - complete_to = " << log.complete_to->version << dendl;
if (is_primary()) {
dout(10) << "activate - starting recovery" << dendl;
} else {
missing.add(po->poid.oid, v, eversion_t());
missing_loc[po->poid.oid].insert(ok_peer);
-
- // primary recovery is log driven
- if (v < info.last_complete) {
- info.last_complete = v;
- init_recovery_pointers();
- }
+ log.last_requested = object_t();
}
uptodate_set.erase(bad_peer);
osd->queue_for_recovery(this);
hash_set<osd_reqid_t> caller_ops;
// recovery pointers
- list<Entry>::iterator requested_to; // not inclusive of referenced item
list<Entry>::iterator complete_to; // not inclusive of referenced item
+ object_t last_requested; // last object requested by primary
/****/
IndexedLog() {}
reset_recovery_pointers();
}
void reset_recovery_pointers() {
- requested_to = log.end();
complete_to = log.end();
+ last_requested = object_t();
}
bool logged_object(object_t oid) const {
virtual void cancel_recovery() = 0;
virtual int start_recovery_ops(int max) = 0;
- void init_recovery_pointers();
-
void purge_strays();
int started = 0;
int skipped = 0;
- list<Log::Entry>::iterator p = log.requested_to;
-
- while (p != log.log.end()) {
- assert(log.objects.count(p->oid));
- latest = log.objects[p->oid];
+ map<object_t, Missing::item>::iterator p = missing.missing.lower_bound(log.last_requested);
+ while (p != missing.missing.end()) {
+ assert(log.objects.count(p->first));
+ latest = log.objects[p->first];
assert(latest);
dout(10) << "recover_primary "
- << *p
+ << *latest
<< (latest->is_update() ? " (update)":"")
<< (missing.is_missing(latest->oid) ? " (missing)":"")
<< (pulling.count(latest->oid) ? " (pulling)":"")
<< (waiting_for_head.count(latest->oid) ? " (waiting for head)":"")
<< dendl;
+
+ assert(latest->is_update());
- if (latest->is_update() &&
- !pulling.count(latest->oid) &&
- missing.is_missing(latest->oid)) {
+ if (!pulling.count(latest->oid)) {
if (waiting_for_head.count(latest->oid)) {
++skipped;
} else {
p++;
- // only advance requested_to if we haven't skipped anything
+ // only advance last_requested if we haven't skipped anything
if (!skipped)
- log.requested_to = p;
+ log.last_requested = latest->oid;
}
// done?
info.last_complete = info.last_update;
}
- log.complete_to = log.log.end();
- log.requested_to = log.log.end();
+ log.reset_recovery_pointers();
uptodate_set.insert(osd->whoami);
if (is_all_uptodate()) {