]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: Store list of hardlinks on the inode of primary link
authorKotresh HR <khiremat@redhat.com>
Tue, 4 Mar 2025 06:19:46 +0000 (11:49 +0530)
committerKotresh HR <khiremat@redhat.com>
Tue, 4 Mar 2025 06:19:46 +0000 (11:49 +0530)
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 <khiremat@redhat.com>
src/include/cephfs/types.h

index c9da5068924106f2de56f9887ef224e95ec8ff0c..d5452fc6811c89344d2c0ae4f65a2fbdbb6a2aae 100644 (file)
@@ -839,6 +839,12 @@ struct inode_t {
     optmetadata.del_opt(optmetadata_singleton_server_t::kind_t::CHARMAP);
   }
 
+  const std::vector<uint64_t>& 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_singleton_server_t,Allocator> optmetadata;
 
   inodeno_t remote_ino = 0; // referent inode - remote inode link
+  std::vector<uint64_t> referent_inodes;
 
 private:
   bool older_is_consistent(const inode_t &other) const;
@@ -1016,6 +1023,8 @@ void inode_t<Allocator>::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<Allocator>::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<Allocator>::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<template<typename> class Allocator>
@@ -1280,6 +1295,7 @@ void inode_t<Allocator>::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<template<typename> class Allocator>
@@ -1326,7 +1342,8 @@ int inode_t<Allocator>::compare(const inode_t<Allocator> &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;