}
void index(pg_log_dup_t& e) {
- if (PGLOG_INDEXED_DUPS) {
+ if (indexed_data & PGLOG_INDEXED_DUPS) {
dup_index[e.reqid] = &e;
}
}
void unindex(const pg_log_dup_t& e) {
- if (PGLOG_INDEXED_DUPS) {
+ if (indexed_data & PGLOG_INDEXED_DUPS) {
auto i = dup_index.find(e.reqid);
if (i != dup_index.end()) {
dup_index.erase(i);
missing.get_items().at(
missing.get_rmissing().begin()->second
).need) {
+ assert(log.complete_to != log.log.end());
++log.complete_to;
}
assert(log.complete_to != log.log.end());
// strip out and ignore ERROR entries
mempool::osd_pglog::list<pg_log_entry_t> entries;
eversion_t last;
+ bool seen_non_error = false;
for (list<pg_log_entry_t>::const_iterator i = orig_entries.begin();
i != orig_entries.end();
++i) {
// all entries are on hoid
assert(i->soid == hoid);
- if (i != orig_entries.begin() && i->prior_version != eversion_t()) {
+ // did not see error entries before this entry and this entry is not error
+ // then this entry is the first non error entry
+ bool first_non_error = ! seen_non_error && ! i->is_error();
+ if (! i->is_error() ) {
+ // see a non error entry now
+ seen_non_error = true;
+ }
+
+ // No need to check the first entry since it prior_version is unavailable
+ // in the list
+ // No need to check if the prior_version is the minimal version
+ // No need to check the first non-error entry since the leading error
+ // entries are not its prior version
+ if (i != orig_entries.begin() && i->prior_version != eversion_t() &&
+ ! first_non_error) {
// in increasing order of version
assert(i->version > last);
// prior_version correct (unless it is an ERROR entry)
assert(i->prior_version == last || i->is_error());
}
- last = i->version;
if (i->is_error()) {
ldpp_dout(dpp, 20) << __func__ << ": ignoring " << *i << dendl;
} else {
ldpp_dout(dpp, 20) << __func__ << ": keeping " << *i << dendl;
entries.push_back(*i);
+ last = i->version;
}
}
if (entries.empty()) {
coll_t log_coll,
ghobject_t log_oid,
const pg_info_t &info,
+ bool force_rebuild_missing,
ostringstream &oss,
bool tolerate_divergent_missing_log,
bool debug_verify_stored_missing = false
) {
return read_log_and_missing(
store, pg_coll, log_coll, log_oid, info,
- log, missing, oss,
+ log, missing, force_rebuild_missing, oss,
tolerate_divergent_missing_log,
&clear_divergent_priors,
this,
const pg_info_t &info,
IndexedLog &log,
missing_type &missing,
+ bool force_rebuild_missing,
ostringstream &oss,
bool tolerate_divergent_missing_log,
bool *clear_divergent_priors = nullptr,
eversion_t on_disk_rollback_info_trimmed_to = eversion_t();
ObjectMap::ObjectMapIterator p = store->get_omap_iterator(log_coll, log_oid);
map<eversion_t, hobject_t> divergent_priors;
- bool has_divergent_priors = false;
missing.may_include_deletes = false;
list<pg_log_entry_t> entries;
list<pg_log_dup_t> dups;
::decode(divergent_priors, bp);
ldpp_dout(dpp, 20) << "read_log_and_missing " << divergent_priors.size()
<< " divergent_priors" << dendl;
- has_divergent_priors = true;
+ assert(force_rebuild_missing);
debug_verify_stored_missing = false;
} else if (p->key() == "can_rollback_to") {
::decode(on_disk_can_rollback_to, bp);
std::move(entries),
std::move(dups));
- if (has_divergent_priors || debug_verify_stored_missing) {
+ if (force_rebuild_missing || debug_verify_stored_missing) {
// build missing
if (debug_verify_stored_missing || info.last_complete < info.last_update) {
ldpp_dout(dpp, 10)
}
}
} else {
- assert(has_divergent_priors);
+ assert(force_rebuild_missing);
for (map<eversion_t, hobject_t>::reverse_iterator i =
divergent_priors.rbegin();
i != divergent_priors.rend();
}
}
- if (!has_divergent_priors) {
+ if (!force_rebuild_missing) {
if (clear_divergent_priors)
(*clear_divergent_priors) = false;
missing.flush();