map_cache(cct, cct->_conf->osd_map_cache_size),
map_bl_cache(cct->_conf->osd_map_cache_size),
map_bl_inc_cache(cct->_conf->osd_map_cache_size),
- in_progress_split_lock("OSDService::in_progress_split_lock"),
stat_lock("OSDService::stat_lock"),
full_status_lock("OSDService::full_status_lock"),
cur_state(NONE),
#endif
-void OSDService::_start_split(spg_t parent, const set<spg_t> &children)
-{
- for (set<spg_t>::const_iterator i = children.begin();
- i != children.end();
- ++i) {
- dout(10) << __func__ << ": Starting split on pg " << *i
- << ", parent=" << parent << dendl;
- assert(!pending_splits.count(*i));
- assert(!in_progress_splits.count(*i));
- pending_splits.insert(make_pair(*i, parent));
-
- assert(!rev_pending_splits[parent].count(*i));
- rev_pending_splits[parent].insert(*i);
- }
-}
-
-void OSDService::mark_split_in_progress(spg_t parent, const set<spg_t> &children)
-{
- Mutex::Locker l(in_progress_split_lock);
- map<spg_t, set<spg_t> >::iterator piter = rev_pending_splits.find(parent);
- assert(piter != rev_pending_splits.end());
- for (set<spg_t>::const_iterator i = children.begin();
- i != children.end();
- ++i) {
- assert(piter->second.count(*i));
- assert(pending_splits.count(*i));
- assert(!in_progress_splits.count(*i));
- assert(pending_splits[*i] == parent);
-
- pending_splits.erase(*i);
- piter->second.erase(*i);
- in_progress_splits.insert(*i);
- }
- if (piter->second.empty())
- rev_pending_splits.erase(piter);
-}
-
-void OSDService::cancel_pending_splits_for_parent(spg_t parent)
-{
- Mutex::Locker l(in_progress_split_lock);
- _cancel_pending_splits_for_parent(parent);
-}
-
-void OSDService::_cancel_pending_splits_for_parent(spg_t parent)
-{
- map<spg_t, set<spg_t> >::iterator piter = rev_pending_splits.find(parent);
- if (piter == rev_pending_splits.end())
- return;
-
- for (set<spg_t>::iterator i = piter->second.begin();
- i != piter->second.end();
- ++i) {
- assert(pending_splits.count(*i));
- assert(!in_progress_splits.count(*i));
- pending_splits.erase(*i);
- dout(10) << __func__ << ": Completing split on pg " << *i
- << " for parent: " << parent << dendl;
- _cancel_pending_splits_for_parent(*i);
- }
- rev_pending_splits.erase(piter);
-}
-
-void OSDService::_maybe_split_pgid(OSDMapRef old_map,
- OSDMapRef new_map,
- spg_t pgid,
- set<spg_t> *new_children)
-{
- if (!old_map->have_pg_pool(pgid.pool())) {
- return;
- }
- int old_pgnum = old_map->get_pg_num(pgid.pool());
- int new_pgnum = get_possibly_deleted_pool_pg_num(new_map, pgid.pool());
- if (pgid.ps() < static_cast<unsigned>(old_pgnum)) {
- set<spg_t> children;
- if (pgid.is_split(old_pgnum, new_pgnum, &children)) {
- _start_split(pgid, children);
- for (auto pgid : children) {
- new_children->insert(pgid);
- }
- }
- } else {
- assert(pgid.ps() < static_cast<unsigned>(new_pgnum));
- }
-}
-
-void OSDService::init_splits_between(spg_t pgid,
- OSDMapRef frommap,
- OSDMapRef tomap,
- set<spg_t> *new_children)
-{
- // First, check whether we can avoid this potentially expensive check
- if (!frommap->have_pg_pool(pgid.pool())) {
- return;
- }
- int old_pgnum = frommap->get_pg_num(pgid.pool());
- int new_pgnum = get_possibly_deleted_pool_pg_num(tomap, pgid.pool());
- if (pgid.is_split(old_pgnum, new_pgnum, NULL)) {
- dout(20) << __func__ << " " << pgid << " from " << frommap->get_epoch()
- << " -> "
- << tomap->get_epoch() << " enumerating split children" << dendl;
- // Ok, a split happened, so we need to walk the osdmaps
- set<spg_t> new_pgs; // pgs to scan on each map
- new_pgs.insert(pgid);
- OSDMapRef curmap(get_map(frommap->get_epoch()));
- for (epoch_t e = frommap->get_epoch() + 1;
- e <= tomap->get_epoch();
- ++e) {
- OSDMapRef nextmap(try_get_map(e));
- if (!nextmap) {
- dout(10) << __func__ << " " << pgid << " missing map " << e << dendl;
- continue;
- }
- if (!nextmap->have_pg_pool(pgid.pool())) {
- dout(20) << __func__ << " " << pgid << " pool deleted in "
- << nextmap->get_epoch()
- << dendl;
- break;
- }
- set<spg_t> even_newer_pgs; // pgs added in this loop
- for (set<spg_t>::iterator i = new_pgs.begin(); i != new_pgs.end(); ++i) {
- set<spg_t> split_pgs;
- if (i->is_split(curmap->get_pg_num(i->pool()),
- nextmap->get_pg_num(i->pool()),
- &split_pgs)) {
- start_split(*i, split_pgs);
- even_newer_pgs.insert(split_pgs.begin(), split_pgs.end());
- new_children->insert(split_pgs.begin(), split_pgs.end());
- }
- }
- new_pgs.insert(even_newer_pgs.begin(), even_newer_pgs.end());
- curmap = nextmap;
- }
- dout(20) << __func__ << " " << pgid << " from " << frommap->get_epoch() << " -> "
- << tomap->get_epoch() << " children " << new_pgs << dendl;
- }
-}
-
-void OSDService::expand_pg_num(OSDMapRef old_map,
- OSDMapRef new_map,
- set<spg_t> *new_children)
-{
- Mutex::Locker l(in_progress_split_lock);
- for (auto pgid : in_progress_splits) {
- _maybe_split_pgid(old_map, new_map, pgid, new_children);
- }
- for (auto i : pending_splits) {
- _maybe_split_pgid(old_map, new_map, i.first, new_children);
- }
-}
-
-bool OSDService::splitting(spg_t pgid)
-{
- Mutex::Locker l(in_progress_split_lock);
- return in_progress_splits.count(pgid) ||
- pending_splits.count(pgid);
-}
-
-void OSDService::complete_split(spg_t pgid)
-{
- Mutex::Locker l(in_progress_split_lock);
- dout(10) << __func__ << ": Completing split on pg " << pgid << dendl;
- assert(!pending_splits.count(pgid));
- assert(in_progress_splits.count(pgid));
- in_progress_splits.erase(pgid);
-}
-
void OSDService::identify_split_children(
OSDMapRef old_map,
void shutdown_reserver();
void shutdown();
-private:
- // split
- Mutex in_progress_split_lock;
- // splits are "pending" after OSD has consumed the map indicating the PG should
- // split but the PG has not yet processed the map.
- map<spg_t, spg_t> pending_splits; // child -> parent
- map<spg_t, set<spg_t> > rev_pending_splits; // parent -> [children]
-
- // splits are "in progress" after the PG has gotten the map, and we hold the
- // parent lock, but the children have not yet been created.
- set<spg_t> in_progress_splits; // child
-
-public:
- void _start_split(spg_t parent, const set<spg_t> &children);
- void start_split(spg_t parent, const set<spg_t> &children) {
- Mutex::Locker l(in_progress_split_lock);
- return _start_split(parent, children);
- }
- void mark_split_in_progress(spg_t parent, const set<spg_t> &pgs);
- void complete_split(spg_t pgid);
- void cancel_pending_splits_for_parent(spg_t parent);
- void _cancel_pending_splits_for_parent(spg_t parent);
- bool splitting(spg_t pgid);
- void expand_pg_num(OSDMapRef old_map,
- OSDMapRef new_map,
- set<spg_t> *new_children);
- void _maybe_split_pgid(OSDMapRef old_map,
- OSDMapRef new_map,
- spg_t pgid,
- set<spg_t> *new_children);
- void init_splits_between(spg_t pgid, OSDMapRef frommap, OSDMapRef tomap,
- set<spg_t> *new_chilren);
-
// -- stats --
Mutex stat_lock;
osd_stat_t osd_stat;