From: Kotresh HR Date: Tue, 25 Feb 2025 11:23:39 +0000 (+0530) Subject: multi-mds/unlink: Unlink referent inode on dentry replicas X-Git-Tag: v20.3.0~377^2~22 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=42d88f4072f6df16bdff3a36ddcc8d5bf5413824;p=ceph.git multi-mds/unlink: Unlink referent inode on dentry replicas If the dentry being deleted is a secondary hardlink with referent inode and is replicated, the dentry replicas mdses gets notified to unlink the inode. The referent inode needs to be unlinked in this case. This patch takes care of handling the same in 'handle_dentry_unlink'. Also, the straydn is created with remote referent to remove the referent inode. The straydn needs to be sent to straydn replicas and dentry replicas of hardlink which gets handled in 'handle_dentry_unlink'. This patch contains this change as well. Fixes: https://tracker.ceph.com/issues/54205 Signed-off-by: Kotresh HR --- diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 12f24f326dcd..166f90e3054d 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -11550,6 +11550,7 @@ void MDCache::handle_dentry_unlink(const cref_t &m) // open inode? if (dnl->is_primary()) { + dout(7) << __func__ << " primary dentry " << *dn << dendl; CInode *in = dnl->get_inode(); dn->dir->unlink_inode(dn); ceph_assert(straydn); @@ -11578,6 +11579,26 @@ void MDCache::handle_dentry_unlink(const cref_t &m) migrator->export_caps(in); straydn = NULL; + } else if (dnl->is_referent_remote()) { + dout(7) << __func__ << " remote referent dentry " << *dn << dendl; + CInode *ref_in = dnl->get_referent_inode(); + dn->dir->unlink_inode(dn); + ceph_assert(straydn); + straydn->dir->link_primary_inode(straydn, ref_in); + + // ref_in->first is lazily updated on replica; drag it forward so + // that we always keep it in sync with the dnq + ceph_assert(straydn->first >= ref_in->first); + ref_in->first = straydn->first; + + //No snapshots on referent - ignore snaprealm invalidate + + // send caps to auth (if we're not already) + if (ref_in->is_any_caps() && + !ref_in->state_test(CInode::STATE_EXPORTINGCAPS)) + migrator->export_caps(ref_in); + + straydn = nullptr; } else { ceph_assert(!straydn); ceph_assert(dnl->is_remote()); diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 0b955005bdd9..5ff75fc969d7 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -8044,7 +8044,7 @@ void Server::_link_remote_finish(const MDRequestRef& mdr, bool inc, if (inc) mdcache->send_dentry_link(dn, null_ref); else - mdcache->send_dentry_unlink(dn, NULL, null_ref); + mdcache->send_dentry_unlink(dn, straydn ? straydn : nullptr, null_ref); // bump target popularity mds->balancer->hit_inode(targeti, META_POP_IWR);