]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
multi-mds/unlink: Unlink referent inode on dentry replicas
authorKotresh HR <khiremat@redhat.com>
Tue, 25 Feb 2025 11:23:39 +0000 (16:53 +0530)
committerKotresh HR <khiremat@redhat.com>
Tue, 4 Mar 2025 06:20:47 +0000 (11:50 +0530)
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 <khiremat@redhat.com>
src/mds/MDCache.cc
src/mds/Server.cc

index 12f24f326dcdc0900a20fc713ed93b9912d897c6..166f90e3054d69d517cde691df2337926f8424c9 100644 (file)
@@ -11550,6 +11550,7 @@ void MDCache::handle_dentry_unlink(const cref_t<MDentryUnlink> &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<MDentryUnlink> &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());
index 0b955005bdd91d2fae63903c41802711f8887fcf..5ff75fc969d7580bd84eccd07e4c827a67d57a0b 100644 (file)
@@ -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);