@@ -3337,45 +3337,49 @@ void PeeringState::proc_master_log(
33373337 bool invalidate_stats = false ;
33383338
33393339 // For partial writes we may be able to keep some of the divergent entries
3340- if (olog.head < pg_log.get_head ()) {
3340+ if (pool. info . allows_ecoptimizations () && ( olog.head < pg_log.get_head () )) {
33413341 // Iterate backwards to divergence
33423342 auto p = pg_log.get_log ().log .end ();
3343- while (true ) {
3344- if (p == pg_log.get_log ().log .begin ()) {
3345- break ;
3346- }
3343+ while (p != pg_log.get_log ().log .begin ()) {
33473344 --p;
3348- if (p->version . version <= olog.head . version ) {
3345+ if (p->version <= olog.head ) {
33493346 break ;
33503347 }
33513348 }
3352- // See if we can wind forward partially written entries
3353- map<pg_shard_t , pg_info_t > all_info (peer_info.begin (), peer_info.end ());
3354- all_info[pg_whoami] = info;
3355- // Normal case is that both logs have entry olog.head
3356- bool can_check_next_entry = (p->version == olog.head );
3357- if ((p->version < olog.head ) || (p == pg_log.get_log ().log .begin ())) {
3349+ if (p == pg_log.get_log ().log .end ()) {
3350+ // Empty log - probably due to a PG split - nothing to do
3351+ } else {
33583352 // After a PG split there may be gaps in the log where entries were
33593353 // split to the other PG. This can result in olog.head being ahead
33603354 // of p->version. So long as there are no entries in olog between
33613355 // p->version and olog.head we can still try to wind forward
33623356 // partially written entries
33633357 auto op = olog.log .end ();
33643358 if (op == olog.log .begin ()) {
3365- can_check_next_entry = true ;
3366- } else if (op->version .version < p->version .version ) {
3367- can_check_next_entry = true ;
3359+ // Other log is emtpy
3360+ if (p->version <= olog.head ) {
3361+ consider_adjusting_pwlc (p->version );
3362+ ++p;
3363+ } else {
3364+ consider_adjusting_pwlc (pg_log.get_tail ());
3365+ }
3366+ } else if (op->version == p->version ) {
3367+ // Normal case - both logs have this entry
3368+ consider_adjusting_pwlc (p->version );
3369+ ++p;
3370+ } else if (op->version < p->version ) {
3371+ // Last entry in other log is before this entry
3372+ consider_adjusting_pwlc (pg_log.get_tail ());
3373+ } else {
3374+ // Other log is ahead of the primary log - give up
3375+ p = pg_log.get_log ().log .end ();
33683376 }
33693377 }
3370- if (can_check_next_entry) {
3371- consider_adjusting_pwlc (p-> version );
3372- }
3378+ // See if we can wind forward partially written entries
3379+ map< pg_shard_t , pg_info_t > all_info (peer_info. begin (), peer_info. end () );
3380+ all_info[pg_whoami] = info;
33733381 PGLog::LogEntryHandlerRef rollbacker{pl->get_log_handler (t)};
3374- while (can_check_next_entry) {
3375- ++p;
3376- if (p == pg_log.get_log ().log .end ()) {
3377- break ;
3378- }
3382+ while (p != pg_log.get_log ().log .end ()) {
33793383 if (p->is_written_shard (from.shard )) {
33803384 psdout (10 ) << " entry " << p->version << " has written shards "
33813385 << p->written_shards << " so is divergent" << dendl;
@@ -3415,15 +3419,16 @@ void PeeringState::proc_master_log(
34153419 psdout (20 ) << " keeping entry " << p->version << dendl;
34163420 invalidate_stats = true ;
34173421 eversion_t previous_version;
3418- if (p == pg_log.get_log ().log .begin ()) {
3419- previous_version = pg_log.get_tail ();
3420- } else {
3421- previous_version = std::prev (p)->version ;
3422- }
3423- rollbacker.get ()->partial_write (&info, previous_version, *p);
3424- olog.head = p->version ;
3422+ if (p == pg_log.get_log ().log .begin ()) {
3423+ previous_version = pg_log.get_tail ();
3424+ } else {
3425+ previous_version = std::prev (p)->version ;
3426+ }
3427+ rollbacker.get ()->partial_write (&info, previous_version, *p);
3428+ olog.head = p->version ;
34253429
3426- // We need to continue processing the log, so don't break.
3430+ // Process the next entry
3431+ ++p;
34273432 }
34283433 }
34293434 // merge log into our own log to build master log. no need to
0 commit comments