]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: Refuse to commit/rollforward beyond end of log.
authorAlex Ainscow <aainscow@uk.ibm.com>
Tue, 13 May 2025 11:55:14 +0000 (12:55 +0100)
committerAlex Ainscow <aainscow@uk.ibm.com>
Wed, 25 Jun 2025 22:36:40 +0000 (23:36 +0100)
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 <aainscow@uk.ibm.com>
src/osd/PeeringState.cc

index 779995507fd8ff5c4169320872d2c262118fa234..d1eded648418bc89b3aebe14d608b6063fe8d085 100644 (file)
@@ -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