]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
osd: Make scrub determine the correct object size.
authorAlex Ainscow <aainscow@uk.ibm.com>
Wed, 8 Oct 2025 10:54:49 +0000 (11:54 +0100)
committerAlex Ainscow <aainscow@uk.ibm.com>
Mon, 13 Oct 2025 10:24:19 +0000 (11:24 +0100)
Signed-off-by: Alex Ainscow <aainscow@uk.ibm.com>
src/osd/ECBackend.h
src/osd/ECSwitch.h
src/osd/PG.h
src/osd/PGBackend.h
src/osd/ReplicatedBackend.h
src/osd/scrubber/scrub_backend.cc
src/osd/scrubber/scrub_backend.h
src/osd/scrubber_common.h
src/test/osd/test_scrubber_be.cc

index c8b9ccdef97138250eccdbecf637e92bb69a9f67..e23cd127a0c18c0d081cb3790e8aefec1538639d 100644 (file)
@@ -373,8 +373,12 @@ public:
       ScrubMap::object &o
     );
 
-  uint64_t be_get_ondisk_size(uint64_t logical_size, shard_id_t shard_id
-    ) const {
+  uint64_t be_get_ondisk_size(uint64_t logical_size, shard_id_t shard_id,
+      bool object_is_legacy_ec) const {
+    if (object_is_legacy_ec) {
+      // In legacy EC, all shards were padded to the next chunk boundry.
+      return sinfo.ro_offset_to_next_chunk_offset(logical_size);
+    }
     return object_size_to_shard_size(logical_size, shard_id);
   }
 };
index 94f165a74dd49011b5604ac0efb90145b2167ecc..e20aacab5a0c2a19bf07612bc9fd9845d9b21c57 100644 (file)
@@ -293,10 +293,11 @@ public:
   }
 
   uint64_t be_get_ondisk_size(uint64_t logical_size,
-                              shard_id_t shard_id) const final {
+                              shard_id_t shard_id,
+                              bool object_is_legacy_ec) const final {
     if (is_optimized())
     {
-      return optimized.be_get_ondisk_size(logical_size, shard_id);
+      return optimized.be_get_ondisk_size(logical_size, shard_id, object_is_legacy_ec);
     }
     return legacy.be_get_ondisk_size(logical_size);
   }
index 3bef1c8c5e4426bdd7efaa7da143517099694fe0..40dfc459409571e950fb1b31493603d5cc8a7420 100644 (file)
@@ -1414,8 +1414,9 @@ public:
  }
 
  uint64_t logical_to_ondisk_size(uint64_t logical_size,
-                                 shard_id_t shard_id) const final {
-   return get_pgbackend()->be_get_ondisk_size(logical_size, shard_id_t(shard_id));
+                                 shard_id_t shard_id,
+                                 bool object_is_legacy_ec) const final {
+   return get_pgbackend()->be_get_ondisk_size(logical_size, shard_id_t(shard_id), object_is_legacy_ec);
  }
 
  bool ec_can_decode(const shard_id_set &available_shards) const final {
index 768eee302cd4527f6140d103c242d944977ca0a1..50a8455c54c13a9d7ab3f9d8c2455ddac1af63d9 100644 (file)
@@ -624,7 +624,8 @@ typedef std::shared_ptr<const OSDMap> OSDMapRef;
      ScrubMapBuilder &pos);
 
    virtual uint64_t be_get_ondisk_size(uint64_t logical_size,
-                                       shard_id_t shard_id) const = 0;
+                                       shard_id_t shard_id,
+                                       bool object_is_legacy_ec) const = 0;
 
    virtual int be_deep_scrub(
      [[maybe_unused]] const Scrub::ScrubCounterSet& io_counters,
index a1cd8a84f12a0fdac53224b53e4f77c936f7beed..d814315d95a92a5fae44346986b542bece8de1bf 100644 (file)
@@ -475,7 +475,8 @@ private:
     ScrubMap::object &o) override;
 
   uint64_t be_get_ondisk_size(uint64_t logical_size,
-                              shard_id_t unused) const final {
+                              shard_id_t unused,
+                              bool unused2) const final {
     return logical_size;
   }
 };
index 8def2cef721327d074f68308b37a3d61281fb3fb..98d0dbe65d194b87c0c5b193ba2f33eed901eadf 100644 (file)
@@ -116,9 +116,29 @@ ScrubBackend::ScrubBackend(ScrubBeListener& scrubber,
 }
 
 uint64_t ScrubBackend::logical_to_ondisk_size(uint64_t logical_size,
-                                 shard_id_t shard_id) const
+                                 shard_id_t shard_id,
+                                 bool hinfo_present,
+                                 uint64_t expected_size) const
 {
-  return m_pg.logical_to_ondisk_size(logical_size, shard_id);
+  uint64_t ondisk_size = m_pg.logical_to_ondisk_size(logical_size, shard_id, false);
+
+  if (!hinfo_present || ondisk_size == expected_size) {
+    return ondisk_size;
+  }
+
+  // This object does not match the expected size, but hinfo is present. In this
+  // case there are valid reasons for the shard to be *either* size when using
+  // optimised EC. The following function checks the expected size from legacy
+  // EC.
+  uint64_t legacy_ondisk_size = m_pg.logical_to_ondisk_size(logical_size, shard_id, true);
+  if (expected_size == legacy_ondisk_size) {
+    return legacy_ondisk_size;
+  }
+
+  // If this return is reached, then the size is corrupt and what we return
+  // here is relevant to the error message only.  Return the non-legacy value
+  // as it might be more useful in debug.
+  return ondisk_size;
 }
 
 uint32_t ScrubBackend::generate_zero_buffer_crc(shard_id_t shard_id,
@@ -819,7 +839,9 @@ shard_as_auth_t ScrubBackend::possible_auth_shard(const hobject_t& obj,
     }
   }
 
-  uint64_t ondisk_size = logical_to_ondisk_size(oi.size, srd.shard);
+  uint64_t ondisk_size = logical_to_ondisk_size(oi.size, srd.shard,
+    smap_obj.attrs.contains(ECUtil::get_hinfo_key()),
+    smap_obj.size);
   if (test_error_cond(smap_obj.size != ondisk_size, shard_info,
                       &shard_info_wrapper::set_obj_size_info_mismatch)) {
 
@@ -1500,7 +1522,9 @@ bool ScrubBackend::compare_obj_details(pg_shard_t auth_shard,
   // ------------------------------------------------------------------------
 
   // sizes:
-  uint64_t oi_size = logical_to_ondisk_size(auth_oi.size, shard.shard);
+  uint64_t oi_size = logical_to_ondisk_size(auth_oi.size, shard.shard,
+  candidate.attrs.contains(ECUtil::get_hinfo_key()),
+  candidate.size);
   if (oi_size != candidate.size) {
     fmt::format_to(std::back_inserter(out),
                    "{}size {} != size {} from auth oi {}",
@@ -1682,12 +1706,17 @@ void ScrubBackend::scrub_snapshot_metadata(ScrubMap& map, const pg_shard_t &srd)
     }
 
     if (oi) {
-      if (logical_to_ondisk_size(oi->size, srd.shard) != p->second.size) {
+      bool has_hinfo = p->second.attrs.contains(
+        ECLegacy::ECUtilL::get_hinfo_key());
+      if (logical_to_ondisk_size(oi->size, srd.shard, has_hinfo, p->second.size)
+          != p->second.size) {
         clog.error() << m_mode_desc << " " << m_pg_id << " " << soid
                       << " : on disk size (" << p->second.size
                       << ") does not match object info size (" << oi->size
                       << ") adjusted for ondisk to ("
-                      << logical_to_ondisk_size(oi->size, srd.shard) << ")";
+                      << logical_to_ondisk_size(oi->size, srd.shard,
+                                                has_hinfo, p->second.size)
+                      << ")";
         soid_error.set_size_mismatch();
         this_chunk->m_error_counts.shallow_errors++;
       }
index 7b0bdaf1d9ebba955ed6914dca6aab0e3fc086aa..1950242617791a7cf4b78ccf55d803097a7e92eb 100644 (file)
@@ -556,7 +556,9 @@ class ScrubBackend {
 
   // accessing the PG backend for this translation service
   uint64_t logical_to_ondisk_size(uint64_t logical_size,
-                                 shard_id_t shard_id) const;
+                                 shard_id_t shard_id,
+                                 bool object_is_legacy_ec = false,
+                                 uint64_t expected_size = 0) const;
   uint32_t generate_zero_buffer_crc(shard_id_t shard_id, int length) const;
 };
 
index b814d01fa85a7baac52ce4ed276a9fce3ec2161c..76ca94a7085a3a03732b283046600d41b53b7f45 100644 (file)
@@ -266,7 +266,8 @@ struct PgScrubBeListener {
 
   // query the PG backend for the on-disk size of an object
   virtual uint64_t logical_to_ondisk_size(uint64_t logical_size,
-                                 shard_id_t shard_id) const = 0;
+                                 shard_id_t shard_id,
+                                 bool object_is_legacy_ec) const = 0;
 
   // used to verify our "cleanliness" before scrubbing
   virtual bool is_waiting_for_unreadable_object() const = 0;
index 4bab20dd889e8a225da79c87734e78d323c5920a..42d493375e3f6ffeb7f3842f968fba0364c10255 100644 (file)
@@ -95,7 +95,8 @@ class TestPg : public PgScrubBeListener {
   const pg_info_t& get_pg_info(ScrubberPasskey) const final { return m_info; }
 
   uint64_t logical_to_ondisk_size(uint64_t logical_size,
-                                  shard_id_t shard_id) const final
+                                  shard_id_t shard_id,
+                                  bool unused) const final
   {
     return logical_size;
   }