If the replay period expires while we are still in the activating
state, we can simply insert our list of requests at the front of
the waiting_for_active list.
Fixes: #13116
Signed-off-by: Sage Weil <sage@redhat.com>
(cherry picked from commit
d18cf51d9419819cdda3782b188b010969288911)
PG *pg = _lookup_lock_pg_with_map_lock_held(pgid);
pg_map_lock.unlock();
dout(10) << "check_replay_queue " << *pg << dendl;
- if (pg->is_active() &&
- pg->is_replay() &&
+ if ((pg->is_active() || pg->is_activating()) &&
+ pg->is_replay() &&
pg->is_primary() &&
pg->replay_until == p->second) {
- pg->replay_queued_ops();
+ pg->replay_queued_ops();
}
pg->unlock();
} else {
void PG::replay_queued_ops()
{
assert(is_replay());
+ assert(is_active() || is_activating());
eversion_t c = info.last_update;
list<OpRequestRef> replay;
dout(10) << "replay_queued_ops" << dendl;
replay.push_back(p->second);
}
replay_queue.clear();
- requeue_ops(replay);
- requeue_ops(waiting_for_active);
- assert(waiting_for_peered.empty());
+ if (is_active()) {
+ requeue_ops(replay);
+ requeue_ops(waiting_for_active);
+ assert(waiting_for_peered.empty());
+ } else {
+ waiting_for_active.splice(waiting_for_active.begin(), replay);
+ }
publish_stats_to_osd();
}
int get_state() const { return state; }
bool is_active() const { return state_test(PG_STATE_ACTIVE); }
+ bool is_activating() const { return state_test(PG_STATE_ACTIVATING); }
bool is_peering() const { return state_test(PG_STATE_PEERING); }
bool is_down() const { return state_test(PG_STATE_DOWN); }
bool is_replay() const { return state_test(PG_STATE_REPLAY); }