push_wq("push_wq", cct->_conf->osd_recovery_thread_timeout, &osd->recovery_tp),
gen_wq("gen_wq", cct->_conf->osd_recovery_thread_timeout, &osd->recovery_tp),
class_handler(osd->class_handler),
+ pg_epoch_lock("OSDService::pg_epoch_lock"),
publish_lock("OSDService::publish_lock"),
pre_publish_lock("OSDService::pre_publish_lock"),
sched_scrub_lock("OSDService::sched_scrub_lock"), scrubs_pending(0),
pg_map[pgid] = pg;
+ service.pg_add_epoch(pg->info.pgid, createmap->get_epoch());
+
pg->lock(no_lockdep_check);
pg->get("PGMap"); // because it's in pg_map
return pg;
epoch_t e(service.get_osdmap()->get_epoch());
pg->get("PGMap"); // For pg_map
pg_map[pg->info.pgid] = pg;
+ service.pg_add_epoch(pg->info.pgid, pg->get_osdmap()->get_epoch());
dout(10) << "Adding newly split pg " << *pg << dendl;
vector<int> up, acting;
pg->get_osdmap()->pg_to_up_acting_osds(pg->info.pgid.pgid, up, acting);
lastmap = nextmap;
handle.reset_tp_timeout();
}
+ service.pg_update_epoch(pg->info.pgid, lastmap->get_epoch());
pg->handle_activate_map(rctx);
}
);
remove_wq.queue(make_pair(PGRef(pg), deleting));
+ service.pg_remove_epoch(pg->info.pgid);
+
// remove from map
pg_map.erase(pg->info.pgid);
pg->put("PGMap"); // since we've taken it out of map
void dequeue_pg(PG *pg, list<OpRequestRef> *dequeued);
+ // -- map epoch lower bound --
+ Mutex pg_epoch_lock;
+ multiset<epoch_t> pg_epochs;
+ map<spg_t,epoch_t> pg_epoch;
+
+ void pg_add_epoch(spg_t pgid, epoch_t epoch) {
+ Mutex::Locker l(pg_epoch_lock);
+ map<spg_t,epoch_t>::iterator t = pg_epoch.find(pgid);
+ assert(t == pg_epoch.end());
+ pg_epoch[pgid] = epoch;
+ pg_epochs.insert(epoch);
+ }
+ void pg_update_epoch(spg_t pgid, epoch_t epoch) {
+ Mutex::Locker l(pg_epoch_lock);
+ map<spg_t,epoch_t>::iterator t = pg_epoch.find(pgid);
+ assert(t != pg_epoch.end());
+ pg_epochs.erase(t->second);
+ t->second = epoch;
+ pg_epochs.insert(epoch);
+ }
+ void pg_remove_epoch(spg_t pgid) {
+ Mutex::Locker l(pg_epoch_lock);
+ map<spg_t,epoch_t>::iterator t = pg_epoch.find(pgid);
+ if (t != pg_epoch.end()) {
+ pg_epochs.erase(t->second);
+ pg_epoch.erase(t);
+ }
+ }
+ epoch_t get_min_pg_epoch() {
+ Mutex::Locker l(pg_epoch_lock);
+ if (pg_epochs.empty())
+ return 0;
+ else
+ return *pg_epochs.begin();
+ }
+
// -- superblock --
Mutex publish_lock, pre_publish_lock; // pre-publish orders before publish
OSDSuperblock superblock;