@@ -348,15 +348,16 @@ void OSDService::identify_splits_and_merges(
348348 return ;
349349 }
350350 int old_pgnum = old_map->get_pg_num (pgid.pool ());
351- auto p = osd->pg_num_history .pg_nums .find (pgid.pool ());
352- if (p == osd->pg_num_history .pg_nums .end ()) {
351+ if (!osd->pg_num_history .pg_nums .contains (pgid.pool ())) {
353352 dout (20 ) << __func__ << " " << pgid << " pool " << pgid.pool ()
354353 << " has no history" << dendl;
355354 return ;
356355 }
356+ // The pgid's pool [epoch -> pg_num] map
357+ const auto & pool_pg_num_history_map = osd->pg_num_history .pg_nums [pgid.pool ()];
357358 dout (20 ) << __func__ << " " << pgid << " e" << old_map->get_epoch ()
358359 << " to e" << new_map->get_epoch ()
359- << " pg_nums " << p-> second << dendl;
360+ << " pg_nums " << pool_pg_num_history_map << dendl;
360361 deque<spg_t > queue;
361362 queue.push_back (pgid);
362363 set<spg_t > did;
@@ -365,83 +366,87 @@ void OSDService::identify_splits_and_merges(
365366 queue.pop_front ();
366367 did.insert (cur);
367368 unsigned pgnum = old_pgnum;
368- for (auto q = p->second .lower_bound (old_map->get_epoch ());
369- q != p->second .end () &&
370- q->first <= new_map->get_epoch ();
371- ++q) {
372- if (pgnum < q->second ) {
369+ for (auto map_iter = pool_pg_num_history_map.lower_bound (old_map->get_epoch ());
370+ map_iter != pool_pg_num_history_map.end ();
371+ ++map_iter) {
372+ const auto & [new_epoch, new_pgnum] = *map_iter;
373+ if (new_epoch > new_map->get_epoch ()) {
374+ // don't handle any changes recorded later than new_map's epoch
375+ break ;
376+ }
377+ if (pgnum < new_pgnum) {
373378 // split?
374379 if (cur.ps () < pgnum) {
375380 set<spg_t > children;
376- if (cur.is_split (pgnum, q-> second , &children)) {
377- dout (20 ) << __func__ << " " << cur << " e" << q-> first
378- << " pg_num " << pgnum << " -> " << q-> second
381+ if (cur.is_split (pgnum, new_pgnum , &children)) {
382+ dout (20 ) << __func__ << " " << cur << " e" << new_epoch
383+ << " pg_num " << pgnum << " -> " << new_pgnum
379384 << " children " << children << dendl;
380385 for (auto i : children) {
381- split_children->insert (make_pair (i, q-> first ));
386+ split_children->insert (make_pair (i, new_epoch ));
382387 if (!did.count (i))
383388 queue.push_back (i);
384389 }
385390 }
386- } else if (cur.ps () < q-> second ) {
387- dout (20 ) << __func__ << " " << cur << " e" << q-> first
388- << " pg_num " << pgnum << " -> " << q-> second
391+ } else if (cur.ps () < new_pgnum ) {
392+ dout (20 ) << __func__ << " " << cur << " e" << new_epoch
393+ << " pg_num " << pgnum << " -> " << new_pgnum
389394 << " is a child" << dendl;
390395 // normally we'd capture this from the parent, but it's
391396 // possible the parent doesn't exist yet (it will be
392397 // fabricated to allow an intervening merge). note this PG
393398 // as a split child here to be sure we catch it.
394- split_children->insert (make_pair (cur, q-> first ));
399+ split_children->insert (make_pair (cur, new_epoch ));
395400 } else {
396- dout (20 ) << __func__ << " " << cur << " e" << q-> first
397- << " pg_num " << pgnum << " -> " << q-> second
401+ dout (20 ) << __func__ << " " << cur << " e" << new_epoch
402+ << " pg_num " << pgnum << " -> " << new_pgnum
398403 << " is post-split, skipping" << dendl;
399404 }
400405 } else if (merge_pgs) {
401406 // merge?
402- if (cur.ps () >= q-> second ) {
407+ if (cur.ps () >= new_pgnum ) {
403408 if (cur.ps () < pgnum) {
404409 spg_t parent;
405- if (cur.is_merge_source (pgnum, q-> second , &parent)) {
410+ if (cur.is_merge_source (pgnum, new_pgnum , &parent)) {
406411 set<spg_t > children;
407- parent.is_split (q-> second , pgnum, &children);
408- dout (20 ) << __func__ << " " << cur << " e" << q-> first
409- << " pg_num " << pgnum << " -> " << q-> second
412+ parent.is_split (new_pgnum , pgnum, &children);
413+ dout (20 ) << __func__ << " " << cur << " e" << new_epoch
414+ << " pg_num " << pgnum << " -> " << new_pgnum
410415 << " is merge source, target " << parent
411416 << " , source(s) " << children << dendl;
412- merge_pgs->insert (make_pair (parent, q-> first ));
417+ merge_pgs->insert (make_pair (parent, new_epoch ));
413418 if (!did.count (parent)) {
414419 // queue (and re-scan) parent in case it might not exist yet
415420 // and there are some future splits pending on it
416421 queue.push_back (parent);
417422 }
418423 for (auto c : children) {
419- merge_pgs->insert (make_pair (c, q-> first ));
424+ merge_pgs->insert (make_pair (c, new_epoch ));
420425 if (!did.count (c))
421426 queue.push_back (c);
422427 }
423428 }
424429 } else {
425- dout (20 ) << __func__ << " " << cur << " e" << q-> first
426- << " pg_num " << pgnum << " -> " << q-> second
430+ dout (20 ) << __func__ << " " << cur << " e" << new_epoch
431+ << " pg_num " << pgnum << " -> " << new_pgnum
427432 << " is beyond old pgnum, skipping" << dendl;
428433 }
429434 } else {
430435 set<spg_t > children;
431- if (cur.is_split (q-> second , pgnum, &children)) {
432- dout (20 ) << __func__ << " " << cur << " e" << q-> first
433- << " pg_num " << pgnum << " -> " << q-> second
436+ if (cur.is_split (new_pgnum , pgnum, &children)) {
437+ dout (20 ) << __func__ << " " << cur << " e" << new_epoch
438+ << " pg_num " << pgnum << " -> " << new_pgnum
434439 << " is merge target, source " << children << dendl;
435440 for (auto c : children) {
436- merge_pgs->insert (make_pair (c, q-> first ));
441+ merge_pgs->insert (make_pair (c, new_epoch ));
437442 if (!did.count (c))
438443 queue.push_back (c);
439444 }
440- merge_pgs->insert (make_pair (cur, q-> first ));
445+ merge_pgs->insert (make_pair (cur, new_epoch ));
441446 }
442447 }
443448 }
444- pgnum = q-> second ;
449+ pgnum = new_pgnum ;
445450 }
446451 }
447452}
0 commit comments