]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: Fix incorrect rollback logic for partial write OI 68609/head
authorAlex Ainscow <aainscow@uk.ibm.com>
Fri, 24 Apr 2026 14:57:55 +0000 (15:57 +0100)
committerAlex Ainscow <aainscow@uk.ibm.com>
Wed, 6 May 2026 09:52:18 +0000 (10:52 +0100)
Before this fix, when rolling back an OI, the system used the OI
from the primary to rollback to. This is wrong if the previous
write was a partial write. This may have a few consequences
during recovery (although its not clear any are serious) and in
EC direct reads, where a false-positive version mismatch will be
detected.

The test provided recreates the issue.

The fix provided modifies the rollback as it is being written.

Fixes: https://tracker.ceph.com/issues/76213
Signed-off-by: Alex Ainscow <aainscow@uk.ibm.com>
# Conflicts:
# src/test/osd/TestECFailoverWithPeering.cc

src/osd/PGBackend.cc
src/test/osd/TestECFailoverWithPeering.cc

index e17f4f3909d442d25688f7a6a60b12bd59da1eb6..bb40c28e66c9179e90290d08e475a43d41f7009a 100644 (file)
@@ -672,11 +672,30 @@ void PGBackend::rollback_setattrs(
     }
   }
   if (only_oi) {
-    t->setattr(
-      coll,
-      ghobject_t(hoid, ghobject_t::NO_GEN, get_parent()->whoami_shard().shard),
-      OI_ATTR,
-      to_set[OI_ATTR]);
+    object_info_t oi;
+    auto p = to_set[OI_ATTR].cbegin();
+    decode(oi, p);
+
+    shard_id_t my_shard = get_parent()->whoami_shard().shard;
+    if (oi.shard_versions.contains(my_shard) && oi.shard_versions.at(my_shard) != oi.version) {
+      oi.version = oi.shard_versions.at(my_shard);
+      oi.shard_versions.clear();
+      
+      bufferlist bl;
+      encode(oi, bl, get_osdmap()->get_features(CEPH_ENTITY_TYPE_OSD, nullptr));
+      
+      t->setattr(
+        coll,
+        ghobject_t(hoid, ghobject_t::NO_GEN, my_shard),
+        OI_ATTR,
+        bl);
+    } else {
+      t->setattr(
+        coll,
+        ghobject_t(hoid, ghobject_t::NO_GEN, my_shard),
+        OI_ATTR,
+        to_set[OI_ATTR]);
+    }
   } else {
     t->setattrs(
       coll,
index 2ac088d3975ad15133ca93cc29701a09ac881dab..e06ec7b73ff08241a312ac6d5a9514b8f3d03105 100644 (file)
@@ -453,7 +453,7 @@ TEST_P(TestECFailoverWithPeering, ECSequentialOSDFailoverTest) {
  *
  * Recreate https://tracker.ceph.com/issues/76213
  */
-TEST_P(TestECFailoverWithPeering, DISABLED_RollbackVersionMismatch) {
+TEST_P(TestECFailoverWithPeering, RollbackVersionMismatch) {
   if (k < 3) {
     GTEST_SKIP() << "SnapshotTrimRollbackVersionMismatch requires at least 3 data shards";
   }