* | | |
* _________v__________ | |
* | | | |
+ * | WAIT_LAST_UPDATE | | |
+ * |____________________| | |
+ * | | |
+ * _________v__________ | |
+ * | | | |
* | BUILD_MAP | | |
* |____________________| | |
* | | |
break;
case PG::Scrubber::WAIT_PUSHES:
- if (active_pushes > 0) {
+ if (active_pushes == 0) {
+ scrubber.state = PG::Scrubber::WAIT_LAST_UPDATE;
+ } else {
dout(15) << "wait for pushes to apply" << dendl;
done = true;
+ }
+ break;
+
+ case PG::Scrubber::WAIT_LAST_UPDATE:
+ if (last_update_applied < scrubber.subset_last_update) {
+ // will be requeued by op_applied
+ dout(15) << "wait for EC read/modify/writes to queue" << dendl;
+ done = true;
break;
}
- scrubber.primary_scrubmap_pos.reset();
+
scrubber.state = PG::Scrubber::BUILD_MAP;
+ scrubber.primary_scrubmap_pos.reset();
break;
case PG::Scrubber::BUILD_MAP:
+ assert(last_update_applied >= scrubber.subset_last_update);
+
// build my own scrub map
if (scrub_preempted) {
dout(10) << __func__ << " preempted" << dendl;
break;
case PG::Scrubber::COMPARE_MAPS:
+ assert(last_update_applied >= scrubber.subset_last_update);
assert(scrubber.waiting_on_whom.empty());
scrub_compare_maps();
if (pg.is_peered()) {
if (pg.last_update_ondisk != pg.info.last_update)
out << " luod=" << pg.last_update_ondisk;
+ if (pg.last_update_applied != pg.info.last_update)
+ out << " lua=" << pg.last_update_applied;
}
if (pg.recovery_ops_active)
INACTIVE,
NEW_CHUNK,
WAIT_PUSHES,
+ WAIT_LAST_UPDATE,
BUILD_MAP,
BUILD_MAP_DONE,
WAIT_REPLICAS,
case INACTIVE: ret = "INACTIVE"; break;
case NEW_CHUNK: ret = "NEW_CHUNK"; break;
case WAIT_PUSHES: ret = "WAIT_PUSHES"; break;
+ case WAIT_LAST_UPDATE: ret = "WAIT_LAST_UPDATE"; break;
case BUILD_MAP: ret = "BUILD_MAP"; break;
case BUILD_MAP_DONE: ret = "BUILD_MAP_DONE"; break;
case WAIT_REPLICAS: ret = "WAIT_REPLICAS"; break;
dout(10) << "op_applied version " << applied_version << dendl;
assert(applied_version <= info.last_update);
last_update_applied = applied_version;
+ if (is_primary()) {
+ if (scrubber.active) {
+ if (last_update_applied >= scrubber.subset_last_update) {
+ requeue_scrub(ops_blocked_by_scrub());
+ }
+ } else {
+ assert(scrubber.start == scrubber.end);
+ }
+ }
}
void PrimaryLogPG::eval_repop(RepGather *repop)