summaryrefslogtreecommitdiff
path: root/src/osd/OSD.cc
diff options
context:
space:
mode:
authorSamuel Just <sam.just@inktank.com>2013-05-01 14:59:08 -0700
committerSamuel Just <sam.just@inktank.com>2013-05-01 14:59:08 -0700
commitf4982268f76c44d7d258bf4702437d4ee3c8e11d (patch)
treeef48e5db9914c1d1af915ec057184df597797fad /src/osd/OSD.cc
parent3e0ca62b0fb77eb8b6445ff3ec78b7a18705cad8 (diff)
downloadceph-f4982268f76c44d7d258bf4702437d4ee3c8e11d.tar.gz
OSD: load_pgs() should fill in start_split honestly
In load_pgs(), we previously called assigned children starting at the loaded pg created between its stored epoch and the current osdmap to have that pg as their parent. This is not correct, some of the children may have been split in subsequent epochs from children split in earlier epochs. Instead, do each map individually. Signed-off-by: Samuel Just <sam.just@inktank.com>
Diffstat (limited to 'src/osd/OSD.cc')
-rw-r--r--src/osd/OSD.cc30
1 files changed, 25 insertions, 5 deletions
diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc
index d4b75d88c10..e25c472d782 100644
--- a/src/osd/OSD.cc
+++ b/src/osd/OSD.cc
@@ -1744,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();