From: Alex Ainscow Date: Tue, 13 May 2025 11:55:14 +0000 (+0100) Subject: osd: Refuse to commit/rollforward beyond end of log. X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=912437d47053f92086261e285462ac5b4d8d749a;p=ceph.git osd: Refuse to commit/rollforward beyond end of log. In optimised EC, if transaction is applied to all shards, followed by a partial transaction AND these two transactions overlap, then it is possible for the non-primary shards to commit a version which is after then end of the log. This commit changes the apply_log such that the commit version will be changed to the head of the log in such situations. Signed-off-by: Alex Ainscow --- diff --git a/src/osd/PeeringState.cc b/src/osd/PeeringState.cc index 779995507fd8f..d1eded648418b 100644 --- a/src/osd/PeeringState.cc +++ b/src/osd/PeeringState.cc @@ -4503,6 +4503,20 @@ void PeeringState::append_log( bool transaction_applied, bool async) { + /* With EC optimisations on, it is possible that we are told to commit a + * version we don't have. This happens when the multiple transactions were + * in flight and the last was a partial write. + * While this is technically valid, there are a number of asserts which can + * be avoided by refusing to roll forward beyond the head of the log. + */ + if (pool.info.allows_ecoptimizations()) { + if (roll_forward_to > pg_log.get_head()) { + roll_forward_to = pg_log.get_head(); + } + if (pct > pg_log.get_head()) { + pct = pg_log.get_head(); + } + } /* The primary has sent an info updating the history, but it may not * have arrived yet. We want to make sure that we cannot remember this * write without remembering that it happened in an interval which went