From: Kotresh HR Date: Tue, 4 Mar 2025 06:19:46 +0000 (+0530) Subject: mds: Store list of hardlinks on the inode of primary link X-Git-Tag: v20.3.0~377^2~47 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=7822a588e8ef9f61bc37b5d48ff323194ad57f6d;p=ceph.git mds: Store list of hardlinks on the inode of primary link Hardlink referent inode plumbing continues. In order to solve the snapshot hardlink lookup problem i.e., to be able to identify all the hardlinks from a given file, we need to maintain the list of referent inodes associated with hardlink on the primary link. Now we have two way link between primary link and corresponding hardlink i.e., the hardlink points the primary link and primary link points to all the hardlinks. Fixes: https://tracker.ceph.com/issues/54205 Signed-off-by: Kotresh HR --- diff --git a/src/include/cephfs/types.h b/src/include/cephfs/types.h index c9da5068924..d5452fc6811 100644 --- a/src/include/cephfs/types.h +++ b/src/include/cephfs/types.h @@ -839,6 +839,12 @@ struct inode_t { optmetadata.del_opt(optmetadata_singleton_server_t::kind_t::CHARMAP); } + const std::vector& get_referent_inodes() { return referent_inodes; } + void add_referent_ino(inodeno_t ref_ino) { referent_inodes.push_back(ref_ino); } + void remove_referent_ino(inodeno_t ref_ino) { + referent_inodes.erase(remove(referent_inodes.begin(), referent_inodes.end(), ref_ino), referent_inodes.end()); + } + void encode(ceph::buffer::list &bl, uint64_t features) const; void decode(ceph::buffer::list::const_iterator& bl); void dump(ceph::Formatter *f) const; @@ -944,6 +950,7 @@ struct inode_t { optmetadata_multiton optmetadata; inodeno_t remote_ino = 0; // referent inode - remote inode link + std::vector referent_inodes; private: bool older_is_consistent(const inode_t &other) const; @@ -1016,6 +1023,8 @@ void inode_t::encode(ceph::buffer::list &bl, uint64_t features) const encode(optmetadata, bl, features); encode(remote_ino, bl); + encode(referent_inodes, bl); + ENCODE_FINISH(bl); } @@ -1140,6 +1149,7 @@ void inode_t::decode(ceph::buffer::list::const_iterator &p) if (struct_v >= 21) { decode(remote_ino, p); + decode(referent_inodes, p); } DECODE_FINISH(p); } @@ -1220,6 +1230,11 @@ void inode_t::dump(ceph::Formatter *f) const f->dump_stream("last_scrub_stamp") << last_scrub_stamp; f->dump_unsigned("last_scrub_version", last_scrub_version); f->dump_unsigned("remote_ino", remote_ino); + f->open_array_section("referent_inodes"); + for (const auto &ri : referent_inodes) { + f->dump_unsigned("referent_inode", ri); + } + f->close_section(); } template class Allocator> @@ -1280,6 +1295,7 @@ void inode_t::decode_json(JSONObj *obj) JSONDecoder::decode_json("last_scrub_stamp", last_scrub_stamp, obj, true); JSONDecoder::decode_json("last_scrub_version", last_scrub_version, obj, true); JSONDecoder::decode_json("remote_ino", remote_ino.val, obj, true); + JSONDecoder::decode_json("referent_inodes", referent_inodes, obj, true); } template class Allocator> @@ -1326,7 +1342,8 @@ int inode_t::compare(const inode_t &other, bool *divergent file_data_version != other.file_data_version || xattr_version != other.xattr_version || backtrace_version != other.backtrace_version || - remote_ino != other.remote_ino) { + remote_ino != other.remote_ino || + referent_inodes != other.referent_inodes) { *divergent = true; } return 0;