Skip to content

Commit 1b44fd9

Browse files
bill-scalesaainscow
authored andcommitted
osd: EC Optimizations proc_master_log boundary case bug fixes
Fix a couple of bugs in proc_master_log for optimized EC pools dealing with boundary conditions such as an empty log and merging two logs that diverge from the very first entry. Refactor the code to handle the boundary conditions and neaten up the code. Predicate the code block with if (pool.info.allows_ecoptimizations()) to make it clear this code path is only for optimized EC pools. Signed-off-by: Bill Scales <[email protected]>
1 parent b178ce4 commit 1b44fd9

File tree

1 file changed

+36
-31
lines changed

1 file changed

+36
-31
lines changed

src/osd/PeeringState.cc

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)