summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Just <sam.just@inktank.com>2013-05-01 16:11:47 -0700
committerSamuel Just <sam.just@inktank.com>2013-05-01 16:11:47 -0700
commitc194151a85892fd204f24f29b03ba1effc49873c (patch)
treebb90ecbe1887e5857b8240d571d0af05c4e63bf4
parent615b84b1fd21a28536ba698a0cb5ba92f7340e22 (diff)
parentf4982268f76c44d7d258bf4702437d4ee3c8e11d (diff)
downloadceph-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.cc36
-rw-r--r--src/osd/OSD.h1
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);