]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds,include: compare optmetadata fields to figure out inode divergence 65324/head
authorRishabh Dave <ridave@redhat.com>
Mon, 1 Sep 2025 14:16:27 +0000 (19:46 +0530)
committerRishabh Dave <ridave@redhat.com>
Wed, 8 Oct 2025 15:44:20 +0000 (21:14 +0530)
Fixes: https://tracker.ceph.com/issues/70188
Signed-off-by: Rishabh Dave <ridave@redhat.com>
src/include/cephfs/types.h

index 8c53e5fed56b3da0e3e30ae341d1e8b42215de26..893830437f0ac11f40a15ea64b16b9c6ad0e235d 100644 (file)
@@ -568,6 +568,26 @@ struct optmetadata_singleton {
     return u64kind < other.u64kind;
   }
 
+  bool operator == (const optmetadata_singleton& other) const {
+    if (this->get_kind() != other.get_kind()) {
+      return false;
+    }
+
+    return std::visit(
+      [](auto& this_optmetadata, auto& other_optmetadata)
+      {
+       // FIXME: optmetadata's can be an instance of unknown_md_t or
+       // charmap_md_t. former should memcmp() since there's no other way but
+       // latter should not. See https://tracker.ceph.com/issues/73382.
+       return memcmp(&this_optmetadata, &other_optmetadata, sizeof(this_optmetadata)) == 0;
+      },
+      optmetadata, other.optmetadata);
+  }
+
+  bool operator != (const optmetadata_singleton& other) const {
+    return !(*this == other);
+  }
+
 private:
   uint64_t u64kind = 0;
   optmetadata_t optmetadata;
@@ -642,6 +662,30 @@ struct optmetadata_multiton {
     return opts.size();
   }
 
+  bool operator == (const optmetadata_multiton<optmetadata_singleton<optmetadata_server_t<Allocator>,Allocator>, Allocator>& other) const
+  {
+    if (size() != other.size())
+      return false;
+
+    auto it_this = opts.begin();
+    auto it_other = other.opts.begin();
+    while (it_this != opts.end() && it_other != opts.end()) {
+      if (*it_this != *it_other) {
+        return false;
+      }
+
+      ++it_this;
+      ++it_other;
+    }
+
+    return true;
+  }
+
+  bool operator != (const optmetadata_multiton<optmetadata_singleton<optmetadata_server_t<Allocator>,Allocator>, Allocator>& other) const
+  {
+    return !(*this == other);
+  }
+
 private:
   optvec_t opts;
 };
@@ -1158,7 +1202,6 @@ auto inode_t<Allocator>::generate_test_instances() -> std::list<inode_t>
 template<template<typename> class Allocator>
 int inode_t<Allocator>::compare(const inode_t<Allocator> &other, bool *divergent) const
 {
-  // TODO: fscrypt / optmetadata: https://tracker.ceph.com/issues/70188
   ceph_assert(ino == other.ino);
   *divergent = false;
   if (version == other.version) {
@@ -1193,6 +1236,7 @@ int inode_t<Allocator>::compare(const inode_t<Allocator> &other, bool *divergent
        fscrypt_auth != other.fscrypt_auth ||
        fscrypt_file != other.fscrypt_file ||
        fscrypt_last_block != other.fscrypt_last_block ||
+       optmetadata != other.optmetadata ||
        remote_ino != other.remote_ino ||
        referent_inodes != other.referent_inodes) {
       *divergent = true;