]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: nonprimary shards are permitted to have a crt newer than head
authorAlex Ainscow <aainscow@uk.ibm.com>
Tue, 29 Apr 2025 10:59:24 +0000 (11:59 +0100)
committerAlex Ainscow <aainscow@uk.ibm.com>
Wed, 25 Jun 2025 22:36:40 +0000 (23:36 +0100)
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 <aainscow@uk.ibm.com>
src/osd/PGLog.h
src/osd/PeeringState.cc
src/tools/ceph_objectstore_tool.cc

index 7aa3d17f1f6e1c1fb14289044c381c4ccba140e7..329a968509a4a6e60cfd6a2bafc031b1256dbb98 100644 (file)
@@ -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(); }
index 55743361ce9636be358b534c9690ab2b938cd816..779995507fd8ff5c4169320872d2c262118fa234 100644 (file)
@@ -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;
 }
 
index 81b86a0767eeca28a9205116efe046aceefc5c49..95fc83d56320430e55e9f20f5f28803c3c5f8f10 100644 (file)
@@ -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;