]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: Commit referent inode to disk
authorKotresh HR <khiremat@redhat.com>
Tue, 18 Feb 2025 18:49:14 +0000 (00:19 +0530)
committerKotresh HR <khiremat@redhat.com>
Tue, 4 Mar 2025 06:20:47 +0000 (11:50 +0530)
Hardlink referent inode plumbing work continues.
This patch adds the capability to commit the
referent inode created (would be part of hardlink
operation) to the disk.

The referent inode is marked with 'r'. If the
recovery tools recover the referent inode,
it's marked with 'R'

Fixes: https://tracker.ceph.com/issues/54205
Signed-off-by: Kotresh HR <khiremat@redhat.com>
src/mds/CDir.cc
src/mds/CDir.h

index 0e406086d4cfe370c00402d9649e07f1cca15ca7..ad8c419c5e0a64fdc15453d590f69d5ca9c05fbd 100644 (file)
@@ -2602,6 +2602,14 @@ void CDir::_omap_commit_ops(int r, int op_prio, int64_t metapool, version_t vers
     if (item.is_remote) {
       // remote link
       CDentry::encode_remote(item.ino, item.d_type, item.alternate_name, bl);
+    } else if (item.is_referent_remote) {
+      // marker, name, inode, [symlink string]
+      bl.append('r');         // inode
+
+      ENCODE_START(2, 1, bl);
+      encode(item.alternate_name, bl);
+      _encode_primary_inode_base(item, dfts, bl);
+      ENCODE_FINISH(bl);
     } else {
       // marker, name, inode, [symlink string]
       bl.append('i');         // inode
@@ -2749,6 +2757,27 @@ void CDir::_parse_dentry(CDentry *dn, dentry_commit_item &item,
     item.ino = linkage.get_remote_ino();
     item.d_type = linkage.get_remote_d_type();
     dout(14) << " dn '" << dn->get_name() << "' remote ino " << item.ino << dendl;
+  } else if (linkage.is_referent_remote()) {
+    // referent link
+    item.is_referent_remote = true;
+    item.ino = linkage.get_remote_ino();
+    item.d_type = linkage.get_remote_d_type();
+
+    CInode *in = linkage.get_referent_inode();
+    ceph_assert(in);
+
+    dout(14) << __func__ << " dn '" << dn->get_name() << "' referent inode " << *in << " remote ino " << item.ino << dendl;
+
+    item.features = mdcache->mds->mdsmap->get_up_features();
+    item.inode = in->inode;
+    if (in->inode->is_symlink())
+      item.symlink = in->symlink;
+    using ceph::encode;
+    encode(in->dirfragtree, bl);
+    item.xattrs = in->xattrs;
+    item.old_inodes = in->old_inodes;
+    item.oldest_snap = in->oldest_snap;
+    item.damage_flags = in->damage_flags;
   } else if (linkage.is_primary()) {
     // primary link
     CInode *in = linkage.get_inode();
@@ -2882,6 +2911,23 @@ void CDir::_committed(int r, version_t v)
     CDentry *dn = *p;
     ++p;
     
+    // referent inode
+    if (dn->linkage.is_referent_remote()) {
+      CInode *in = dn->linkage.get_referent_inode();
+      ceph_assert(in);
+      ceph_assert(in->is_auth());
+
+      if (committed_version >= in->get_version()) {
+       if (in->is_dirty()) {
+         dout(15) << __func__ << " referent inode - dir " << committed_version << " >= inode " << in->get_version() << " now clean " << *in << dendl;
+         in->mark_clean();
+       }
+      } else {
+       dout(15) << __func__ << " referent inode - dir " << committed_version << " < inode " << in->get_version() << " still dirty " << *in << dendl;
+       ceph_assert(in->is_dirty() || in->last < CEPH_NOSNAP);  // special case for cow snap items (not predirtied)
+      }
+    }
+
     // inode?
     if (dn->linkage.is_primary()) {
       CInode *in = dn->linkage.get_inode();
index 9c477eac598299a46f4195776c7b2b72c6d7d66a..bfdb363d98a5f5be7742c53ffe8ae49f2a5f3176 100644 (file)
@@ -61,6 +61,7 @@ public:
     std::string key;
     snapid_t first;
     bool is_remote = false;
+    bool is_referent_remote = false;
 
     inodeno_t ino;
     unsigned char d_type;