]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
osd: Do not apply log entry if shard not written
authorBill Scales <bill_scales@uk.ibm.com>
Thu, 19 Jun 2025 13:26:04 +0000 (14:26 +0100)
committerAlex Ainscow <aainscow@uk.ibm.com>
Sun, 7 Sep 2025 23:10:41 +0000 (00:10 +0100)
This was a failed test, where the primary concluded that all objects were present
despite one missing object on the non primary shard.

The problem was caused because the log entries are sent to the unwritten shards if that
shard is missing in order to update the version number in the missing object. However,
the log entry should not actually be added to the log.

Further testing showed there are other scenarios where log entries are sent to
unwritten shards (for example a clone + partial_write in the same transaction),
these scenarios do not want to add the log entry either.

Signed-off-by: Bill Scales <bill_scales@uk.ibm.com>
(cherry picked from commit 24cd772f2099aa5f7dfeb7609522f770d0ae1115)

src/osd/PeeringState.cc

index 4514cfc1a5ce02989c604fabbd03d46c89cbcf8b..d8b0af10cb214e1616fdf24277da0ce791133d1a 100644 (file)
@@ -4536,8 +4536,20 @@ void PeeringState::add_log_entry(const pg_log_entry_t& e, ObjectStore::Transacti
   // log mutation
   enum PGLog::NonPrimary nonprimary{pool.info.is_nonprimary_shard(info.pgid.shard)};
   PGLog::LogEntryHandlerRef handler{pl->get_log_handler(t)};
-  pg_log.add(e, nonprimary, applied, &info, handler.get());
-  psdout(10) << "add_log_entry " << e << dendl;
+  /* Normally an unwritten shard does not get told about a log entry. However
+   * there are exceptions - in these cases we want to skip adding the entry
+   * to the log.
+   */
+  if (e.is_written_shard(pg_whoami.shard)) {
+    pg_log.add(e, nonprimary, applied, &info, handler.get());
+    psdout(10) << "add_log_entry " << e << dendl;
+  } else {
+    psdout(10) << "add_log_entry skipping partial write " << e << dendl;
+    eversion_t head = pg_log.get_head();
+    ceph_assert(e.version > head);
+    ceph_assert(head.version == 0 || e.version.version > head.version);
+    pg_log.set_head(e.version);
+  }
 }