From 6209c8cdf980f261c60073d4535d745f24538a7d Mon Sep 17 00:00:00 2001 From: Alex Ainscow Date: Tue, 29 Apr 2025 11:59:24 +0100 Subject: [PATCH] osd: nonprimary shards are permitted to have a crt newer than head Non-primary shards do not get updates for some transactions. It is possible however for other transactions to increase the can_rollback_to to a later version. This causes an assert for some operations. Signed-off-by: Alex Ainscow --- src/osd/PGLog.h | 27 +++++++++++++++++++++++---- src/osd/PeeringState.cc | 3 ++- src/tools/ceph_objectstore_tool.cc | 2 +- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/osd/PGLog.h b/src/osd/PGLog.h index 7aa3d17f1f6e1..329a968509a4a 100644 --- a/src/osd/PGLog.h +++ b/src/osd/PGLog.h @@ -133,6 +133,11 @@ struct PGLog : DoutPrefixProvider { return cct; } + enum NonPrimary : bool { + NonPrimaryFalse = false, + NonPrimaryTrue = true + }; + ////////////////////////////// sub classes ////////////////////////////// struct LogEntryHandler { virtual void rollback( @@ -611,9 +616,13 @@ public: } // actors - void add(const pg_log_entry_t& e, bool applied = true) { + void add(const pg_log_entry_t& e, enum NonPrimary nonprimary, bool applied) { if (!applied) { - ceph_assert(get_can_rollback_to() == head); + if (!nonprimary) { + ceph_assert(get_can_rollback_to() == head); + } else { + ceph_assert(get_can_rollback_to() >= head); + } } // make sure our buffers don't pin bigger buffers @@ -653,6 +662,12 @@ public: } } // add + // nonprimary and applied must either both be provided or neither. If + // neither is provided applied = true and the nonprimary is irrelevant. + void add(const pg_log_entry_t& e) { + add(e, NonPrimaryFalse, true); + } + void trim( CephContext* cct, eversion_t s, @@ -820,9 +835,13 @@ public: void unindex() { log.unindex(); } - void add(const pg_log_entry_t& e, bool applied = true) { + void add(const pg_log_entry_t& e, enum NonPrimary nonprimary, bool applied) { mark_writeout_from(e.version); - log.add(e, applied); + log.add(e, nonprimary, applied); + } + + void add(const pg_log_entry_t& e) { + add(e, NonPrimaryFalse, true); } void reset_recovery_pointers() { log.reset_recovery_pointers(); } diff --git a/src/osd/PeeringState.cc b/src/osd/PeeringState.cc index 55743361ce963..779995507fd8f 100644 --- a/src/osd/PeeringState.cc +++ b/src/osd/PeeringState.cc @@ -4488,7 +4488,8 @@ void PeeringState::add_log_entry(const pg_log_entry_t& e, bool applied) info.last_user_version = e.user_version; // log mutation - pg_log.add(e, applied); + enum PGLog::NonPrimary nonprimary{pool.info.is_nonprimary_shard(info.pgid.shard)}; + pg_log.add(e, nonprimary, applied); psdout(10) << "add_log_entry " << e << dendl; } diff --git a/src/tools/ceph_objectstore_tool.cc b/src/tools/ceph_objectstore_tool.cc index 81b86a0767eec..95fc83d563204 100644 --- a/src/tools/ceph_objectstore_tool.cc +++ b/src/tools/ceph_objectstore_tool.cc @@ -1183,7 +1183,7 @@ int expand_log( for (; e <= target_version; e.version++) { entry.version = e; std::cout << "adding " << e << std::endl; - log.add(entry, true); + log.add(entry); } info.last_complete = target_version; info.last_update = target_version; -- 2.39.5