Skip to content

Commit e0e8117

Browse files
bill-scalesaainscow
authored andcommitted
osd: Optimized EC proc_master_log fix roll-forward logic when shard is absent
Fix bug in optimized EC code where proc_master_log incorrectly did not roll forward a write if one of the written shards is missing in the current epoch and there is a stray version of that shard that did not receive the write. As long as the currently present shards that participated in les and were updated by a write have the update then the write should be rolled-forward. Signed-off-by: Bill Scales <[email protected]>
1 parent f1826fd commit e0e8117

File tree

1 file changed

+20
-3
lines changed

1 file changed

+20
-3
lines changed

src/osd/PeeringState.cc

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3401,7 +3401,19 @@ void PeeringState::proc_master_log(
34013401
// See if we can wind forward partially written entries
34023402
map<pg_shard_t, pg_info_t> all_info(peer_info.begin(), peer_info.end());
34033403
all_info[pg_whoami] = info;
3404+
epoch_t max_last_epoch_started;
3405+
eversion_t min_last_update_acceptable;
3406+
calculate_maxles_and_minlua(all_info,
3407+
max_last_epoch_started,
3408+
min_last_update_acceptable);
34043409
PGLog::LogEntryHandlerRef rollbacker{pl->get_log_handler(t)};
3410+
shard_id_set shards_currently_present;
3411+
for (auto&& [pg_shard, pi] : all_info) {
3412+
if ((pi.last_update >= min_last_update_acceptable) &&
3413+
(pi.last_epoch_started >= max_last_epoch_started)) {
3414+
shards_currently_present.insert(pg_shard.shard);
3415+
}
3416+
}
34053417
while (p != pg_log.get_log().log.end()) {
34063418
if (p->is_written_shard(from.shard)) {
34073419
psdout(10) << "entry " << p->version << " has written shards "
@@ -3432,13 +3444,18 @@ void PeeringState::proc_master_log(
34323444
}
34333445
psdout(20) << "shards_with_update=" << shards_with_update
34343446
<< " shards_without_update=" << shards_without_update
3447+
<< " shards_currently_present=" << shards_currently_present
34353448
<< dendl;
3436-
if (!shards_without_update.empty()) {
3437-
// A shard is missing this write - this is the first divergent entry
3449+
if (!shard_id_set::intersection(shards_without_update,
3450+
shards_currently_present).empty()) {
3451+
// One or more of the currently present shards is missing this write - this
3452+
// is the first divergent entry
34383453
break;
34393454
}
34403455
// This entry can be kept, only shards that didn't participate in
3441-
// the partial write missed the update
3456+
// the partial write or are not currently present missed the update.
3457+
// If shards are not currently present there are still enough remaining
3458+
// shards to reconstruct the data.
34423459
psdout(20) << "keeping entry " << p->version << dendl;
34433460
invalidate_stats = true;
34443461
eversion_t previous_version;

0 commit comments

Comments
 (0)