// periodically kick recovery work queue
recovery_tp.wake();
- if (scrub_should_schedule()) {
- sched_scrub();
- }
+ sched_scrub();
map_lock.get_read();
PG *pg = p->second;
pg->lock();
if (pg->is_primary()) {
- if (m->repair)
- pg->state_set(PG_STATE_REPAIR);
- if (pg->queue_scrub()) {
- dout(10) << "queueing " << *pg << " for scrub" << dendl;
- }
+ pg->unreg_scrub();
+ pg->must_scrub = true;
+ pg->must_repair = m->repair;
+ pg->reg_scrub();
+ dout(10) << "marking " << *pg << " for scrub" << dendl;
}
pg->unlock();
}
PG *pg = pg_map[*p];
pg->lock();
if (pg->is_primary()) {
- if (m->repair)
- pg->state_set(PG_STATE_REPAIR);
- if (pg->queue_scrub()) {
- dout(10) << "queueing " << *pg << " for scrub" << dendl;
- }
+ pg->unreg_scrub();
+ pg->must_scrub = true;
+ pg->must_repair = m->repair;
+ pg->reg_scrub();
+ dout(10) << "marking " << *pg << " for scrub" << dendl;
}
pg->unlock();
}
{
assert(osd_lock.is_locked());
- dout(20) << "sched_scrub" << dendl;
+ bool should = scrub_should_schedule();
+
+ dout(20) << "sched_scrub should=" << (int)should << dendl;
pair<utime_t,pg_t> pos;
utime_t max = ceph_clock_now(g_ceph_context);
sched_scrub_lock.Unlock();
PG *pg = _lookup_lock_pg(pgid);
if (pg) {
- if (pg->is_active() && !pg->sched_scrub()) {
+ if (pg->is_active() &&
+ (should || pg->must_scrub) &&
+ !pg->sched_scrub()) {
pg->unlock();
sched_scrub_lock.Lock();
break;
if (is_scrubbing()) {
return false;
}
+ must_scrub = false;
state_set(PG_STATE_SCRUBBING);
osd->scrub_wq.queue(this);
return true;
void PG::reg_scrub()
{
+ if (must_scrub) {
+ scrub_reg_stamp = utime_t();
+ } else {
scrub_reg_stamp = info.history.last_scrub_stamp;
+ }
osd->reg_last_pg_scrub(info.pgid, scrub_reg_stamp);
}
if (!is_primary() || !is_active() || !is_clean() || !is_scrubbing()) {
dout(10) << "scrub -- not primary or active or not clean" << dendl;
- state_clear(PG_STATE_REPAIR);
state_clear(PG_STATE_SCRUBBING);
clear_scrub_reserved();
unlock();
{
assert(_lock.is_locked());
state_clear(PG_STATE_SCRUBBING);
- state_clear(PG_STATE_REPAIR);
update_stats();
// active -> nothing.
osd->requeue_ops(this, waiting_for_active);
+ must_scrub = false;
+ must_repair = false;
+
finalizing_scrub = false;
scrub_block_writes = false;
scrub_active = false;
dout(10) << "scrub_finalize has maps, analyzing" << dendl;
int errors = 0, fixed = 0;
- bool repair = state_test(PG_STATE_REPAIR);
+ bool repair = must_repair;
const char *mode = repair ? "repair":"scrub";
if (acting.size() > 1) {
dout(10) << "scrub comparing replica scrub maps" << dendl;
state_clear(PG_STATE_DOWN);
state_clear(PG_STATE_RECOVERING);
+ must_scrub = false;
+ must_repair = false;
+
peer_missing.clear();
peer_purged.clear();
epoch_t scrub_epoch_start;
ScrubMap primary_scrubmap;
MOSDRepScrub *active_rep_scrub;
+ bool must_scrub, must_repair;
utime_t scrub_reg_stamp;
void repair_object(const hobject_t& soid, ScrubMap::object *po, int bad_peer, int ok_peer);
scrub_reserved(false), scrub_reserve_failed(false),
scrub_waiting_on(0),
active_rep_scrub(0),
+ must_scrub(false), must_repair(false),
recovery_state(this)
{
pool->get();
scrub_clear_state();
} else if (is_scrubbing()) {
state_clear(PG_STATE_SCRUBBING);
- state_clear(PG_STATE_REPAIR);
+ must_scrub = false;
+ must_repair = false;
}
context_registry_on_change();
dout(10) << "_scrub" << dendl;
coll_t c(info.pgid);
- bool repair = state_test(PG_STATE_REPAIR);
+ bool repair = must_repair;
const char *mode = repair ? "repair":"scrub";
// traverse in reverse order.