From: Samuel Just Date: Wed, 1 May 2013 21:59:08 +0000 (-0700) Subject: OSD: load_pgs() should fill in start_split honestly X-Git-Tag: v0.61~19^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f4982268f76c44d7d258bf4702437d4ee3c8e11d;p=ceph.git 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 --- diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index d4b75d88c10c..e25c472d7828 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -1744,12 +1744,32 @@ void OSD::load_pgs() assert(i->second.empty()); } - set 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 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 even_newer_pgs; // pgs added in this loop + for (set::iterator i = new_pgs.begin(); i != new_pgs.end(); ++i) { + set 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();