unsigned split_bits,
IndexedLog *target);
+ void split_pwlc(pg_info_t &info) {
+ eversion_t previous_version;
+ if (rollback_info_trimmed_to_riter == log.rend()) {
+ previous_version = tail;
+ } else {
+ previous_version = rollback_info_trimmed_to_riter->version;
+ }
+ // When a split occurs log entries are divided between the two PGs,
+ // this can leave pwlc refering to entries that are no longer in this
+ // PG log. Update pwlc so it is not beyond the last entry in the log.
+ // Non-primary shards which don't have a full log may rollback pwlc
+ // too far, but this will get corrected by the primary shard when
+ // activating shards later in peering.
+ for (auto & [shard, versionrange] : info.partial_writes_last_complete) {
+ auto &&[old_v, new_v] = versionrange;
+ if (new_v > previous_version) {
+ new_v = previous_version;
+ if (old_v > new_v) {
+ old_v = new_v;
+ }
+ }
+ }
+ }
+
void zero() {
// we must have already trimmed the old entries
ceph_assert(rollback_info_trimmed_to == head);
}
}
+ void split_pwlc(pg_info_t &info) {
+ log.split_pwlc(info);
+ }
+
void merge_from(
const std::vector<PGLog*>& sources,
eversion_t last_update) {
child->info.last_user_version = info.last_user_version;
+ // fix up pwlc - it may refer to log entries that are no longer in the log
child->info.partial_writes_last_complete = info.partial_writes_last_complete;
+ pg_log.split_pwlc(info);
+ child->pg_log.split_pwlc(child->info);
info.log_tail = pg_log.get_tail();
child->info.log_tail = child->pg_log.get_tail();