From: Kotresh HR Date: Tue, 18 Feb 2025 18:49:14 +0000 (+0530) Subject: mds: Commit referent inode to disk X-Git-Tag: v20.3.0~377^2~46 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=8de360960afc474ddbeff2f7ade7824cf74dcc1c;p=ceph.git 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 --- diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index 0e406086d4cf..ad8c419c5e0a 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 9c477eac5982..bfdb363d98a5 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;