diff options
author | Samuel Just <sam.just@inktank.com> | 2013-05-01 16:11:47 -0700 |
---|---|---|
committer | Samuel Just <sam.just@inktank.com> | 2013-05-01 16:11:47 -0700 |
commit | c194151a85892fd204f24f29b03ba1effc49873c (patch) | |
tree | bb90ecbe1887e5857b8240d571d0af05c4e63bf4 | |
parent | 615b84b1fd21a28536ba698a0cb5ba92f7340e22 (diff) | |
parent | f4982268f76c44d7d258bf4702437d4ee3c8e11d (diff) | |
download | ceph-c194151a85892fd204f24f29b03ba1effc49873c.tar.gz |
Merge remote-tracking branch 'upstream/wip_4884' into next
Fixes: #4884
Reviewed-by: Greg Farnum <greg@inktank.com>
-rw-r--r-- | src/osd/OSD.cc | 36 | ||||
-rw-r--r-- | src/osd/OSD.h | 1 |
2 files changed, 32 insertions, 5 deletions
diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index e63361b8ddd..e25c472d782 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -234,6 +234,11 @@ void OSDService::mark_split_in_progress(pg_t parent, const set<pg_t> &children) void OSDService::cancel_pending_splits_for_parent(pg_t parent) { Mutex::Locker l(in_progress_split_lock); + return _cancel_pending_splits_for_parent(parent); +} + +void OSDService::_cancel_pending_splits_for_parent(pg_t parent) +{ map<pg_t, set<pg_t> >::iterator piter = rev_pending_splits.find(parent); if (piter == rev_pending_splits.end()) return; @@ -244,6 +249,7 @@ void OSDService::cancel_pending_splits_for_parent(pg_t parent) assert(pending_splits.count(*i)); assert(!in_progress_splits.count(*i)); pending_splits.erase(*i); + _cancel_pending_splits_for_parent(*i); } rev_pending_splits.erase(piter); } @@ -1738,12 +1744,32 @@ void OSD::load_pgs() assert(i->second.empty()); } - set<pg_t> split_pgs; + // First, check whether we can avoid this potentially expensive check if (osdmap->have_pg_pool(pg->info.pgid.pool()) && - pg->info.pgid.is_split(pg->get_osdmap()->get_pg_num(pg->info.pgid.pool()), - osdmap->get_pg_num(pg->info.pgid.pool()), - &split_pgs)) { - service.start_split(pg->info.pgid, split_pgs); + pg->info.pgid.is_split( + pg->get_osdmap()->get_pg_num(pg->info.pgid.pool()), + osdmap->get_pg_num(pg->info.pgid.pool()), + 0)) { + // Ok, a split happened, so we need to walk the osdmaps + set<pg_t> new_pgs; // pgs to scan on each map + new_pgs.insert(pg->info.pgid); + for (epoch_t e = pg->get_osdmap()->get_epoch() + 1; + e <= osdmap->get_epoch(); + ++e) { + OSDMapRef curmap(get_map(e-1)); + OSDMapRef nextmap(get_map(e)); + set<pg_t> even_newer_pgs; // pgs added in this loop + for (set<pg_t>::iterator i = new_pgs.begin(); i != new_pgs.end(); ++i) { + set<pg_t> split_pgs; + if (i->is_split(curmap->get_pg_num(i->pool()), + nextmap->get_pg_num(i->pool()), + &split_pgs)) { + service.start_split(*i, split_pgs); + even_newer_pgs.insert(split_pgs.begin(), split_pgs.end()); + } + } + new_pgs.insert(even_newer_pgs.begin(), even_newer_pgs.end()); + } } pg->reg_next_scrub(); diff --git a/src/osd/OSD.h b/src/osd/OSD.h index f894768fbe5..a0b05f0818b 100644 --- a/src/osd/OSD.h +++ b/src/osd/OSD.h @@ -398,6 +398,7 @@ public: void mark_split_in_progress(pg_t parent, const set<pg_t> &pgs); void complete_split(const set<pg_t> &pgs); void cancel_pending_splits_for_parent(pg_t parent); + void _cancel_pending_splits_for_parent(pg_t parent); bool splitting(pg_t pgid); void expand_pg_num(OSDMapRef old_map, OSDMapRef new_map); |