]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
erasure-code/consistency: Allow consistency checker to be able to deal with non-4k...
authorJon Bailey <jonathan.bailey1@ibm.com>
Mon, 11 Aug 2025 11:51:42 +0000 (12:51 +0100)
committerJon Bailey <jonathan.bailey1@ibm.com>
Thu, 14 Aug 2025 09:29:44 +0000 (10:29 +0100)
A parity returned to the client will be the size of shard 0, which may not be 4k aligned in optimised erasure coding. A parity returned through the encode function will always be 4k aligned. This change makes it so we truncate the encoded data down to the size of the client write before comparing them together in the consistency check so we know we are comparing them like-for-like

Signed-off-by: Jon Bailey <jonathan.bailey1@ibm.com>
src/erasure-code/consistency/ConsistencyChecker.cc
src/erasure-code/consistency/ECEncoder.cc
src/erasure-code/consistency/ECEncoder.h
src/erasure-code/consistency/ECEncoderSwitch.cc
src/erasure-code/consistency/ECEncoderSwitch.h

index da84ce1a8d1b8b4daf843edc40cfb4703c4de0aa..af41e8e3df45486e33b236440f3856683b7ce295 100644 (file)
@@ -5,6 +5,7 @@
 #include "ECReader.h"
 #include "ECEncoder.h"
 #include "ECEncoderSwitch.h"
+#include "osd/ECUtil.h"
 
 using ConsistencyChecker = ceph::consistency::ConsistencyChecker;
 
@@ -115,6 +116,30 @@ bool ConsistencyChecker::check_object_consistency(const std::string& oid,
     return false;
   }
 
+  // Encode always returns 4k aligned data
+  // A client read will always return parity with the same size as shard 0
+  // We confirm the encoded data is the same or larger than the client read
+  ceph_assert(outbl->length() >= data_and_parity.second.length());
+  // We check the difference is not larger than the page size multipled by the
+  //    number of parities
+  ceph_assert(outbl->length() - data_and_parity.second.length()
+                <= (encoder.get_m() * encoder.get_chunk_size()) - encoder.get_m());
+  // We truncate the encoded parity to the size of the client read for comparison
+  if (outbl->length() != data_and_parity.second.length())
+  {
+    const int aligned_shard_length = outbl->length() / encoder.get_m();
+    const int shard_data_length = data_and_parity.second.length()
+                                  / encoder.get_m();
+    ceph::bufferlist newdata;
+    for (int i = 0; i < encoder.get_m(); i++)
+    {
+      ceph::bufferlist bl;
+      bl.substr_of(*outbl, i * aligned_shard_length, shard_data_length);
+      newdata.append(bl);
+    }
+    outbl = std::move(newdata);
+  }
+
   return buffers_match(outbl.value(), data_and_parity.second);
 }
 
index 504d6d80e2e1c184c085d3ea2465f7cdbd161ff1..3be2f543a7897f08f922ae7b1ef24bbb9ffb4b75 100644 (file)
@@ -198,6 +198,17 @@ int ECEncoder<SInfo>::get_m()
 {
   return stripe_info->get_m();
 }
+
+/**
+ * Return chunksize for the stripe
+ *
+ * @returns int Chunksize for the stripe
+ */
+template <typename SInfo>
+int ECEncoder<SInfo>::get_chunk_size()
+{
+  return stripe_info->get_chunk_size();
+}
 }
 }
 
index 30f3e6d0b03536cbe24ce3a212c122b70b82d8d2..2a5d8befc821382ebcf43259e0eff1e5909aab37 100644 (file)
@@ -29,6 +29,7 @@ class ECEncoder {
     std::optional<ceph::bufferlist> do_encode(ceph::bufferlist inbl);
     int get_k(void);
     int get_m(void);
+    int get_chunk_size(void);
 };
 }
 }
\ No newline at end of file
index 9ab97ebf9d89d3016bb8b161b7e5de52228e8443..7a932afe1e926db784856e9366d3e44a7f976fd0 100644 (file)
@@ -57,3 +57,17 @@ int ECEncoderSwitch::get_m()
     return encoder_legacy.get_m();
   }
 }
+
+/**
+ * Return chunksize for the stripe from the correct version of the encoder
+ *
+ * @returns int Chunksize for stripe
+ */
+int ECEncoderSwitch::get_chunk_size()
+{
+  if (optimizations_enabled) {
+    return encoder_optimized.get_chunk_size();
+  } else {
+    return encoder_legacy.get_chunk_size();
+  }
+}
index d86e911212ab86b08ce46ea3fb9c5fb59f7a6905..8343206d75272d2b4e8ad59d86ccc424c3bdb2bc 100644 (file)
@@ -26,6 +26,7 @@ class ECEncoderSwitch {
     std::optional<ceph::bufferlist> do_encode(ceph::bufferlist inbl);
     int get_k(void);
     int get_m(void);
+    int get_chunk_size(void);
 };
 }
 }