From: Kotresh HR Date: Tue, 25 Feb 2025 12:27:41 +0000 (+0530) Subject: multi-mds/unlink: Referent inode - reverse link mgmt X-Git-Tag: v20.3.0~377^2~21 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=236a4b7b046a717e84879dcd535c0e1fefceab0d;p=ceph.git multi-mds/unlink: Referent inode - reverse link mgmt 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 --- diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 5ff75fc969d..5307cbfef39 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -7899,11 +7899,21 @@ void Server::_link_remote(const MDRequestRef& mdr, bool inc, CDentry *dn, CInode auto req = make_message(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();