osd: fix scrub scheduling for 0.0

The initial value for pair<utime_t,pg_t> can match pg 0.0, preventing it
from being manually scrubbed.  Fix!

Signed-off-by: Sage Weil <sage@inktank.com>
This commit is contained in:
Sage Weil 2013-01-14 18:20:29 -08:00
parent 389bed5d33
commit 26a63df97b
2 changed files with 50 additions and 35 deletions

View File

@ -3575,37 +3575,40 @@ void OSD::sched_scrub()
//dout(20) << " " << last_scrub_pg << dendl;
pair<utime_t, pg_t> pos;
while (service.next_scrub_stamp(pos, &pos)) {
utime_t t = pos.first;
pg_t pgid = pos.second;
if (service.first_scrub_stamp(&pos)) {
do {
utime_t t = pos.first;
pg_t pgid = pos.second;
dout(30) << " " << pgid << " at " << t << dendl;
if (t > min) {
dout(10) << " " << pgid << " at " << t
<< " > min " << min << " (" << g_conf->osd_scrub_min_interval << " seconds ago)" << dendl;
break;
}
if (t > max && !load_is_low) {
// save ourselves some effort
break;
}
PG *pg = _lookup_lock_pg(pgid);
if (pg) {
if (pg->is_active() &&
(load_is_low ||
t < max ||
pg->scrubber.must_scrub)) {
if (t > min) {
dout(10) << " " << pgid << " at " << t
<< (pg->scrubber.must_scrub ? ", explicitly requested" : "")
<< (t < max ? ", last_scrub > max" : "")
<< dendl;
if (pg->sched_scrub()) {
pg->unlock();
break;
}
<< " > min " << min << " (" << g_conf->osd_scrub_min_interval << " seconds ago)" << dendl;
break;
}
pg->unlock();
}
if (t > max && !load_is_low) {
// save ourselves some effort
break;
}
PG *pg = _lookup_lock_pg(pgid);
if (pg) {
if (pg->is_active() &&
(load_is_low ||
t < max ||
pg->scrubber.must_scrub)) {
dout(10) << " " << pgid << " at " << t
<< (pg->scrubber.must_scrub ? ", explicitly requested" : "")
<< (t < max ? ", last_scrub < max" : "")
<< dendl;
if (pg->sched_scrub()) {
pg->unlock();
break;
}
}
pg->unlock();
}
} while (service.next_scrub_stamp(pos, &pos));
}
dout(20) << "sched_scrub done" << dendl;
}

View File

@ -255,17 +255,29 @@ public:
void unreg_last_pg_scrub(pg_t pgid, utime_t t) {
Mutex::Locker l(sched_scrub_lock);
pair<utime_t,pg_t> p(t, pgid);
assert(last_scrub_pg.count(p));
last_scrub_pg.erase(p);
set<pair<utime_t,pg_t> >::iterator it = last_scrub_pg.find(p);
assert(it != last_scrub_pg.end());
last_scrub_pg.erase(it);
}
bool next_scrub_stamp(pair<utime_t, pg_t> after,
bool first_scrub_stamp(pair<utime_t, pg_t> *out) {
Mutex::Locker l(sched_scrub_lock);
if (last_scrub_pg.size() == 0)
return false;
set< pair<utime_t, pg_t> >::iterator iter = last_scrub_pg.begin();
*out = *iter;
return true;
}
bool next_scrub_stamp(pair<utime_t, pg_t> next,
pair<utime_t, pg_t> *out) {
Mutex::Locker l(sched_scrub_lock);
if (last_scrub_pg.size() == 0) return false;
set< pair<utime_t, pg_t> >::iterator iter = last_scrub_pg.lower_bound(after);
if (iter == last_scrub_pg.end()) return false;
if (last_scrub_pg.size() == 0)
return false;
set< pair<utime_t, pg_t> >::iterator iter = last_scrub_pg.lower_bound(next);
if (iter == last_scrub_pg.end())
return false;
++iter;
if (iter == last_scrub_pg.end()) return false;
if (iter == last_scrub_pg.end())
return false;
*out = *iter;
return true;
}