From 8de360960afc474ddbeff2f7ade7824cf74dcc1c Mon Sep 17 00:00:00 2001 From: Kotresh HR Date: Wed, 19 Feb 2025 00:19:14 +0530 Subject: [PATCH] mds: Commit referent inode to disk 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 --- src/mds/CDir.cc | 46 ++++++++++++++++++++++++++++++++++++++++++++++ src/mds/CDir.h | 1 + 2 files changed, 47 insertions(+) diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index 0e406086d4cfe..ad8c419c5e0a6 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -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(); diff --git a/src/mds/CDir.h b/src/mds/CDir.h index 9c477eac59829..bfdb363d98a5f 100644 --- a/src/mds/CDir.h +++ b/src/mds/CDir.h @@ -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; -- 2.39.5