}
void PGLog::merge_log(pg_info_t &oinfo, pg_log_t&& olog, pg_shard_t fromosd,
- pg_info_t &info, LogEntryHandler *rollbacker,
- bool &dirty_info, bool &dirty_big_info)
+ pg_info_t &info, const pg_pool_t &pool, pg_shard_t toosd,
+ LogEntryHandler *rollbacker,
+ bool &dirty_info, bool &dirty_big_info,
+ bool ec_optimizations_enabled)
{
dout(10) << "merge_log " << olog << " from osd." << fromosd
<< " into " << log << dendl;
&log,
missing,
rollbacker,
+ pool,
+ toosd.shard,
this);
_merge_divergent_entries(
missing.add(oid, need, have, is_delete);
}
- void missing_add_next_entry(const pg_log_entry_t& e) {
- missing.add_next_event(e);
+ void missing_add_next_entry(const pg_log_entry_t& e, const pg_pool_t &pool, shard_id_t shard) {
+ missing.add_next_event(e, pool, shard);
}
//////////////////// get or std::set log ////////////////////
void merge_log(pg_info_t &oinfo,
pg_log_t&& olog,
pg_shard_t from,
- pg_info_t &info, LogEntryHandler *rollbacker,
- bool &dirty_info, bool &dirty_big_info);
+ pg_info_t &info,
+ const pg_pool_t &pool,
+ pg_shard_t to,
+ LogEntryHandler *rollbacker,
+ bool &dirty_info, bool &dirty_big_info,
+ bool ec_optimizations_enabled);
template <typename missing_type>
static bool append_log_entries_update_missing(
IndexedLog *log,
missing_type &missing,
LogEntryHandler *rollbacker,
+ const pg_pool_t &pool,
+ shard_id_t shard,
const DoutPrefixProvider *dpp) {
bool invalidate_stats = false;
if (log && !entries.empty()) {
if (p->soid <= last_backfill &&
!p->is_error()) {
if (missing.may_include_deletes) {
- missing.add_next_event(*p);
+ missing.add_next_event(*p, pool, shard);
} else {
if (p->is_delete()) {
missing.rm(p->soid, p->version);
} else {
- missing.add_next_event(*p);
+ missing.add_next_event(*p, pool, shard);
}
if (rollbacker) {
// hack to match PG::mark_all_unfound_lost
bool append_new_log_entries(
const hobject_t &last_backfill,
const mempool::osd_pglog::list<pg_log_entry_t> &entries,
+ pg_info_t *info,
LogEntryHandler *rollbacker,
+ const pg_pool_t &pool,
+ shard_id_t shard,
bool ec_optimizations_enabled) {
bool invalidate_stats = append_log_entries_update_missing(
last_backfill,
&log,
missing,
rollbacker,
+ pool,
+ shard,
this);
if (!entries.empty()) {
mark_writeout_from(entries.begin()->version);
if (perform_deletes_during_peering() && p->is_delete()) {
pm.rm(p->soid, p->version);
} else {
- pm.add_next_event(*p);
+ pm.add_next_event(*p, pool.info, peer.shard);
}
}
}
{
PGLog::LogEntryHandlerRef rollbacker{pl->get_log_handler(t)};
pg_log.merge_log(
- oinfo, std::move(olog), from, info, rollbacker.get(),
- dirty_info, dirty_big_info);
+ oinfo, std::move(olog), from, info, pool.info, pg_whoami,
+ rollbacker.get(), dirty_info, dirty_big_info,
+ pool.info.allows_ecoptimizations());
}
void PeeringState::rewind_divergent_log(
pg_log.append_new_log_entries(
info.last_backfill,
entries,
+ &info,
rollbacker.get(),
+ pool.info,
+ pg_whoami.shard,
pool.info.allows_ecoptimizations());
if (pg_committed_to && entries.rbegin()->soid > info.last_backfill) {
NULL,
pmissing,
NULL,
+ pool.info,
+ peer.shard,
dpp);
pinfo.last_update = info.last_update;
pinfo.stats.stats_invalid = pinfo.stats.stats_invalid || invalidate_stats;
continue;
requires_missing_loc = true;
for (auto &&entry: logv) {
- peer_missing[i].add_next_event(entry);
+ peer_missing[i].add_next_event(entry, pool.info, i.shard);
}
}
/// Update missing set to reflect e (TODOSAM: not sure why this is needed)
void add_local_next_event(const pg_log_entry_t& e) {
- pg_log.missing_add_next_entry(e);
+ pg_log.missing_add_next_entry(e, pool.info, pg_whoami.shard);
}
/// Update log trim boundary
* this needs to be called in log order as we extend the log. it
* assumes missing is accurate up through the previous log entry.
*/
- void add_next_event(const pg_log_entry_t& e) {
+ void add_next_event(const pg_log_entry_t& e, const pg_pool_t &pool, shard_id_t shard) {
std::map<hobject_t, item>::iterator missing_it;
missing_it = missing.find(e.soid);
bool is_missing_divergent_item = missing_it != missing.end();
+ bool skipped = false;
if (e.prior_version == eversion_t() || e.is_clone()) {
// new object.
if (is_missing_divergent_item) { // use iterator
// .have = nil
missing_it->second = item(e.version, eversion_t(), e.is_delete());
missing_it->second.clean_regions.mark_fully_dirty();
+ } else if (pool.is_nonprimary_shard(shard) && !e.is_written_shard(shard)) {
+ // new object, partial write and not already missing - skip
+ skipped = true;
} else {
// create new element in missing map
// .have = nil
missing_it->second.clean_regions.mark_fully_dirty();
else
missing_it->second.clean_regions.merge(e.clean_regions);
+ } else if (pool.is_nonprimary_shard(shard) && !e.is_written_shard(shard)) {
+ // existing object, partial write and not already missing - skip
+ skipped = true;
} else {
// not missing, we must have prior_version (if any)
ceph_assert(!is_missing_divergent_item);
else
missing[e.soid].clean_regions = e.clean_regions;
}
- rmissing[e.version.version] = e.soid;
- tracker.changed(e.soid);
+ if (!skipped) {
+ rmissing[e.version.version] = e.soid;
+ tracker.changed(e.soid);
+ }
}
void revise_need(hobject_t oid, eversion_t need, bool is_delete) {
bool dirty_big_info = false;
merge_log(
oinfo, std::move(olog), pg_shard_t(1, shard_id_t(0)), info,
- &h, dirty_info, dirty_big_info);
+ pg_pool_t(), pg_shard_t(), &h, dirty_info, dirty_big_info, false);
ASSERT_EQ(info.last_update, oinfo.last_update);
verify_missing(tcase, missing);
if (i->is_delete() && tcase.deletes_during_peering) {
omissing.rm(i->soid, i->version);
} else {
- omissing.add_next_event(*i);
+ omissing.add_next_event(*i, pg_pool_t(), shard_id_t());
}
}
}
{
pg_log_entry_t &ne = log.log.front();
ne.op = pg_log_entry_t::MODIFY;
- missing.add_next_event(ne);
+ missing.add_next_event(ne, pg_pool_t(), shard_id_t());
pg_log_entry_t oe;
oe.mark_unrollbackable();
oe.version = eversion_t(1,1);
oe.version = eversion_t(2,1);
oe.op = pg_log_entry_t::MODIFY;
- missing.add_next_event(oe);
+ missing.add_next_event(oe, pg_pool_t(), shard_id_t());
missing.flush();
EXPECT_FALSE(is_dirty());
EXPECT_FALSE(dirty_big_info);
TestHandler h(remove_snap);
- merge_log(oinfo, std::move(olog), fromosd, info, &h,
- dirty_info, dirty_big_info);
+ merge_log(oinfo, std::move(olog), fromosd, info, pg_pool_t(), pg_shard_t(),
+ &h, dirty_info, dirty_big_info, false);
EXPECT_FALSE(missing.have_missing());
EXPECT_EQ(0U, log.log.size());
EXPECT_FALSE(dirty_big_info);
TestHandler h(remove_snap);
- merge_log(oinfo, std::move(olog), fromosd, info, &h,
- dirty_info, dirty_big_info);
+ merge_log(oinfo, std::move(olog), fromosd, info, pg_pool_t(), pg_shard_t(),
+ &h,dirty_info, dirty_big_info, false);
EXPECT_FALSE(missing.have_missing());
EXPECT_EQ(0U, log.log.size());
EXPECT_FALSE(dirty_big_info);
TestHandler h(remove_snap);
- merge_log(oinfo, std::move(olog), fromosd, info, &h,
- dirty_info, dirty_big_info);
+ merge_log(oinfo, std::move(olog), fromosd, info, pg_pool_t(), pg_shard_t(),
+ &h, dirty_info, dirty_big_info, false);
EXPECT_FALSE(missing.have_missing());
EXPECT_EQ(3U, log.log.size());
EXPECT_FALSE(dirty_big_info);
TestHandler h(remove_snap);
- merge_log(oinfo, std::move(olog), fromosd, info, &h,
- dirty_info, dirty_big_info);
+ merge_log(oinfo, std::move(olog), fromosd, info, pg_pool_t(), pg_shard_t(),
+ &h, dirty_info, dirty_big_info, false);
/* When the divergent entry is a DELETE and the authoritative
entry is a MODIFY, the object will be added to missing : it is
TestHandler h(remove_snap);
missing.may_include_deletes = false;
- merge_log(oinfo, std::move(olog), fromosd, info, &h,
- dirty_info, dirty_big_info);
+ merge_log(oinfo, std::move(olog), fromosd, info, pg_pool_t(), pg_shard_t(),
+ &h, dirty_info, dirty_big_info, false);
/* When the divergent entry is a DELETE and the authoritative
entry is a MODIFY, the object will be added to missing : it is
TestHandler h(remove_snap);
missing.may_include_deletes = false;
- merge_log(oinfo, std::move(olog), fromosd, info, &h,
- dirty_info, dirty_big_info);
+ merge_log(oinfo, std::move(olog), fromosd, info, pg_pool_t(), pg_shard_t(),
+ &h, dirty_info, dirty_big_info, false);
EXPECT_FALSE(missing.have_missing());
EXPECT_EQ(2U, log.log.size());
EXPECT_TRUE(e.object_is_indexed());
EXPECT_TRUE(e.reqid_is_indexed());
EXPECT_FALSE(missing.is_missing(oid));
- missing.add_next_event(e);
+ missing.add_next_event(e, pg_pool_t(), shard_id_t());
EXPECT_TRUE(missing.is_missing(oid));
EXPECT_EQ(eversion_t(), missing.get_items().at(oid).have);
EXPECT_EQ(oid, missing.get_rmissing().at(e.version.version));
EXPECT_EQ(1U, missing.get_rmissing().size());
// adding the same object replaces the previous one
- missing.add_next_event(e);
+ missing.add_next_event(e, pg_pool_t(), shard_id_t());
EXPECT_TRUE(missing.is_missing(oid));
EXPECT_EQ(1U, missing.num_missing());
EXPECT_EQ(1U, missing.get_rmissing().size());
EXPECT_TRUE(e.object_is_indexed());
EXPECT_FALSE(e.reqid_is_indexed());
EXPECT_FALSE(missing.is_missing(oid));
- missing.add_next_event(e);
+ missing.add_next_event(e, pg_pool_t(), shard_id_t());
EXPECT_TRUE(missing.is_missing(oid));
EXPECT_EQ(eversion_t(), missing.get_items().at(oid).have);
EXPECT_EQ(oid, missing.get_rmissing().at(e.version.version));
EXPECT_EQ(1U, missing.get_rmissing().size());
// adding the same object replaces the previous one
- missing.add_next_event(e);
+ missing.add_next_event(e, pg_pool_t(), shard_id_t());
EXPECT_TRUE(missing.is_missing(oid));
EXPECT_EQ(1U, missing.num_missing());
EXPECT_EQ(1U, missing.get_rmissing().size());
EXPECT_TRUE(e.object_is_indexed());
EXPECT_TRUE(e.reqid_is_indexed());
EXPECT_FALSE(missing.is_missing(oid));
- missing.add_next_event(e);
+ missing.add_next_event(e, pg_pool_t(), shard_id_t());
EXPECT_TRUE(missing.is_missing(oid));
EXPECT_EQ(eversion_t(), missing.get_items().at(oid).have);
EXPECT_EQ(oid, missing.get_rmissing().at(e.version.version));
// adding the same object with a different version
e.prior_version = prior_version;
- missing.add_next_event(e);
+ missing.add_next_event(e, pg_pool_t(), shard_id_t());
EXPECT_EQ(eversion_t(), missing.get_items().at(oid).have);
EXPECT_TRUE(missing.is_missing(oid));
EXPECT_EQ(1U, missing.num_missing());
EXPECT_TRUE(e.object_is_indexed());
EXPECT_TRUE(e.reqid_is_indexed());
EXPECT_FALSE(missing.is_missing(oid));
- missing.add_next_event(e);
+ missing.add_next_event(e, pg_pool_t(), shard_id_t());
EXPECT_TRUE(missing.is_missing(oid));
EXPECT_EQ(prior_version, missing.get_items().at(oid).have);
EXPECT_EQ(version, missing.get_items().at(oid).need);
EXPECT_TRUE(e.object_is_indexed());
EXPECT_TRUE(e.reqid_is_indexed());
EXPECT_FALSE(missing.is_missing(oid));
- missing.add_next_event(e);
+ missing.add_next_event(e, pg_pool_t(), shard_id_t());
EXPECT_TRUE(missing.is_missing(oid));
e.op = pg_log_entry_t::DELETE;
EXPECT_TRUE(e.is_delete());
- missing.add_next_event(e);
+ missing.add_next_event(e, pg_pool_t(), shard_id_t());
EXPECT_TRUE(missing.is_missing(oid));
EXPECT_TRUE(missing.get_items().at(oid).is_delete());
EXPECT_EQ(prior_version, missing.get_items().at(oid).have);
EXPECT_TRUE(e.object_is_indexed());
EXPECT_TRUE(e.reqid_is_indexed());
EXPECT_FALSE(missing.is_missing(oid));
- missing.add_next_event(e);
+ missing.add_next_event(e, pg_pool_t(), shard_id_t());
EXPECT_TRUE(missing.is_missing(oid));
EXPECT_FALSE(missing.get_items().at(oid).is_delete());
e.op = pg_log_entry_t::LOST_DELETE;
e.version.version++;
EXPECT_TRUE(e.is_delete());
- missing.add_next_event(e);
+ missing.add_next_event(e, pg_pool_t(), shard_id_t());
EXPECT_TRUE(missing.is_missing(oid));
EXPECT_TRUE(missing.get_items().at(oid).is_delete());
EXPECT_EQ(prior_version, missing.get_items().at(oid).have);