From 780bb7fb2f9bf53fa79dfb05e1eb316c0a42cff4 Mon Sep 17 00:00:00 2001 From: Rishabh Dave Date: Mon, 1 Sep 2025 19:46:27 +0530 Subject: [PATCH] mds,include: compare optmetadata fields to figure out inode divergence Fixes: https://tracker.ceph.com/issues/70188 Signed-off-by: Rishabh Dave --- src/include/cephfs/types.h | 46 +++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/src/include/cephfs/types.h b/src/include/cephfs/types.h index 8c53e5fed56b..893830437f0a 100644 --- a/src/include/cephfs/types.h +++ b/src/include/cephfs/types.h @@ -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,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,Allocator>, Allocator>& other) const + { + return !(*this == other); + } + private: optvec_t opts; }; @@ -1158,7 +1202,6 @@ auto inode_t::generate_test_instances() -> std::list template class Allocator> int inode_t::compare(const inode_t &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::compare(const inode_t &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; -- 2.47.3