]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
multi-mds/unlink: Referent inode - reverse link mgmt
authorKotresh HR <khiremat@redhat.com>
Tue, 25 Feb 2025 12:27:41 +0000 (17:57 +0530)
committerKotresh HR <khiremat@redhat.com>
Tue, 4 Mar 2025 06:20:47 +0000 (11:50 +0530)
On unlink of the secondary hardlink with referent
inode, remove the referent inode from the referent_inodes
list of the primary/real inode. This patch handles the
multi-mds scenario where the auth of the primary/real
inode is different from the dentry auth of the secondary
hardlink (also the referent inode auth)

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

index 5ff75fc969d7580bd84eccd07e4c827a67d57a0b..5307cbfef390039934128dce108dcb7ddb21699f 100644 (file)
@@ -7899,11 +7899,21 @@ void Server::_link_remote(const MDRequestRef& mdr, bool inc, CDentry *dn, CInode
     auto req = make_message<MMDSPeerRequest>(mdr->reqid, mdr->attempt, op);
     targeti->set_object_info(req->get_object_info());
     req->op_stamp = mdr->get_op_stamp();
+    // referent inode related
+    req->referent_ino = inodeno_t(0);
     if (mds->mdsmap->allow_referent_inodes()) {
-      if (inc && newi)
+      if (inc && newi) {
         req->referent_ino = newi->ino();
-    } else {
-      req->referent_ino = inodeno_t(0);
+        dout(20) << __func__ << " link - referent_ino= " << req->referent_ino << " sending over wire" << dendl;
+      }
+      else { //unlink
+        if (dnl->is_referent_remote()) {
+          CInode *ref_in = dnl->get_referent_inode();
+          ceph_assert(ref_in->is_auth());
+         req->referent_ino = ref_in->ino();
+          dout(20) << __func__ << " unlink - referent_ino= " << req->referent_ino << " sending over wire" << dendl;
+        }
+      }
     }
 
     if (auto& desti_srnode = mdr->more()->desti_srnode)
@@ -8145,6 +8155,14 @@ void Server::handle_peer_link_prep(const MDRequestRef& mdr)
   } else {
     inc = false;
     pi.inode->nlink--;
+
+    if (referent_ino > 0) {
+      // Remove referent inode from primary inode (targeti)
+      pi.inode->remove_referent_ino(referent_ino);
+      dout(20) << __func__ <<  " referent_inodes " << std::hex << pi.inode->get_referent_inodes()
+               << " referent ino removed " << referent_ino << dendl;
+    }
+
     if (targeti->is_projected_snaprealm_global()) {
       ceph_assert(mdr->peer_request->desti_snapbl.length());
       auto p = mdr->peer_request->desti_snapbl.cbegin();