divergent,
oinfo,
olog.get_can_rollback_to(),
+ olog.get_can_rollback_to(),
omissing,
0,
this);
dout(10) << "rewind_divergent_log truncate divergent future " <<
newhead << dendl;
-
+ // We need to preserve the original crt before it gets updated in rewind_from_head().
+ // Later, in merge_object_divergent_entries(), we use it to check whether we can rollback
+ // a divergent entry or not.
+ eversion_t original_crt = log.get_can_rollback_to();
+ dout(20) << __func__ << " original_crt = " << original_crt << dendl;
if (info.last_complete > newhead)
info.last_complete = newhead;
divergent,
info,
log.get_can_rollback_to(),
+ original_crt,
missing,
rollbacker,
this);
divergent,
info,
log.get_can_rollback_to(),
+ log.get_can_rollback_to(),
missing,
rollbacker,
this);
const mempool::osd_pglog::list<pg_log_entry_t> &orig_entries, ///< [in] entries for hoid to merge
const pg_info_t &info, ///< [in] info for merging entries
eversion_t olog_can_rollback_to, ///< [in] rollback boundary
+ eversion_t original_can_rollback_to, ///< [in] original rollback boundary
missing_type &missing, ///< [in,out] missing to adjust, use
LogEntryHandler *rollbacker, ///< [in] optional rollbacker object
const DoutPrefixProvider *dpp ///< [in] logging provider
const bool object_not_in_store =
!missing.is_missing(hoid) &&
entries.rbegin()->is_delete();
+ ldpp_dout(dpp, 10) << __func__ << ": hoid " << " object_not_in_store: "
+ << object_not_in_store << dendl;
ldpp_dout(dpp, 10) << __func__ << ": hoid " << hoid
<< " prior_version: " << prior_version
<< " first_divergent_update: " << first_divergent_update
for (list<pg_log_entry_t>::const_reverse_iterator i = entries.rbegin();
i != entries.rend();
++i) {
- if (!i->can_rollback() || i->version <= olog_can_rollback_to) {
+ /// Use original_can_rollback_to instead of olog_can_rollback_to to check
+ // if we can rollback or not. This is to ensure that we don't try to rollback
+ // to an object that has been deleted and doesn't exist.
+ if (!i->can_rollback() || i->version <= original_can_rollback_to) {
ldpp_dout(dpp, 10) << __func__ << ": hoid " << hoid << " cannot rollback "
<< *i << dendl;
can_rollback = false;
for (list<pg_log_entry_t>::const_reverse_iterator i = entries.rbegin();
i != entries.rend();
++i) {
- assert(i->can_rollback() && i->version > olog_can_rollback_to);
+ assert(i->can_rollback() && i->version > original_can_rollback_to);
ldpp_dout(dpp, 10) << __func__ << ": hoid " << hoid
<< " rolling back " << *i << dendl;
if (rollbacker)
mempool::osd_pglog::list<pg_log_entry_t> &entries, ///< [in] entries to merge
const pg_info_t &oinfo, ///< [in] info for merging entries
eversion_t olog_can_rollback_to, ///< [in] rollback boundary
+ eversion_t original_can_rollback_to, ///< [in] original rollback boundary
missing_type &omissing, ///< [in,out] missing to adjust, use
LogEntryHandler *rollbacker, ///< [in] optional rollbacker object
const DoutPrefixProvider *dpp ///< [in] logging provider
i->second,
oinfo,
olog_can_rollback_to,
+ original_can_rollback_to,
omissing,
rollbacker,
dpp);
entries,
info,
log.get_can_rollback_to(),
+ log.get_can_rollback_to(),
missing,
rollbacker,
this);