]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
osd: Make scrub determine the correct object size.
authorAlex Ainscow <aainscow@uk.ibm.com>
Thu, 13 Nov 2025 11:22:07 +0000 (11:22 +0000)
committerAlex Ainscow <aainscow@uk.ibm.com>
Thu, 13 Nov 2025 11:25:24 +0000 (11:25 +0000)
Permits shard sizes to be either legacy or new after upgrade

Resolves: rhbz#2400427

Signed-off-by: Alex Ainscow <aainscow@uk.ibm.com>
(cherry picked from commit 9609410db0df8879af4c8aacf2ff37b141d1bbcd)

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 4d116a582a2c94e552fd33d6c3d48720e878cfee..462ff2e9f2218af37dd8066941952d9d4b626eb1 100644 (file)
@@ -363,8 +363,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 42f405021a818651f807581d95028c5c184093ce..24e4f9fb7e99a279bca0d9dca9f86a3f46cb99e2 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 f3e760c1b8fd154c736bccc1838a79f9452b4e91..f8231a72335afaa8a2aab1de9b66039f381bfedc 100644 (file)
@@ -1412,8 +1412,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);
  }
 };
 
index acbff0745b23ef9f27d36a34dd1c12de78e8daf3..bfddeb4bbc499d49ddc7e19ad5d82b22de9d19f9 100644 (file)
@@ -617,7 +617,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 b52fe710181522ff0a0718ebcc133b540f6c0d13..fc00982d0b166899fc9fc19e3a53e98c6061cc76 100644 (file)
@@ -464,7 +464,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 ddb95a011f2c3986bbb6e4c0caa5ed566ae4af07..2c152d5d0cfe3151594e3b26c336bfb44ae73e14 100644 (file)
@@ -99,9 +99,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;
 }
 
 void ScrubBackend::update_repair_status(bool should_repair)
@@ -732,7 +752,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)) {
 
@@ -1327,7 +1349,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 {}",
@@ -1509,12 +1533,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 83abd71981cb4cebee6731bb640a9700ce036f93..f8705ca539a2066d1d45e016f740ae7b17e0f322 100644 (file)
@@ -526,7 +526,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;
 };
 
 namespace fmt {
index d52b57db4bb6976ceac312c818cf487088f29001..7323502bec848ecaa673afb4d00898be40e9cbbc 100644 (file)
@@ -264,7 +264,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 fc183a682cf8503a012788fac514727ea09ce6b9..954fb13343e28727642d3a0aac53407606cfa110 100644 (file)
@@ -91,7 +91,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;
   }