From 36adf82c36148f05a8d647311b3bd20ba0364216 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Fri, 15 Sep 2023 10:56:56 +0800 Subject: [PATCH] mds: fix issuing redundant reintegrate/migrate_stray requests Just in case a CInode's nlink is 1, and then a unlink request comes and then early replies and submits to the MDLogs, but just before the MDlogs are flushed a link request comes, and the link request also succeeds and early replies to client. Later when the unlink/link requests' MDLog events are flushed and the callbacks are called, which will fire a stray denty reintegration. But it will pick the new dentry, which is from the link's request and is a remote dentry, to do the reintegration. While in the 'rename' code when traversing the path it will trigger to call the 'dn->link_remote()', which later will fire a new stray dentry reintegration. The problem is if the first 'rename' request is retried several times, and in each time it will fire a new reintegration, which makes no sense and maybe blocked for a very long time dues to some reasons and then will be reported as slow request warning. Fixes: https://tracker.ceph.com/issues/62702 Signed-off-by: Xiubo Li --- src/mds/CDentry.h | 2 ++ src/mds/MDSRank.h | 2 ++ src/mds/StrayManager.cc | 8 +++++++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/mds/CDentry.h b/src/mds/CDentry.h index 4dca5816ae6ff1..1c2b6f892cec54 100644 --- a/src/mds/CDentry.h +++ b/src/mds/CDentry.h @@ -376,6 +376,8 @@ class CDentry : public MDSCacheObject, public LRUObject, public Counter mempool::mds_co::map client_lease_map; std::map> batch_ops; + ceph_tid_t reintegration_reqid = 0; + protected: friend class Migrator; diff --git a/src/mds/MDSRank.h b/src/mds/MDSRank.h index 63a04a0c843a30..5b97ec288f80a7 100644 --- a/src/mds/MDSRank.h +++ b/src/mds/MDSRank.h @@ -161,8 +161,10 @@ struct MDSMetaRequest { op(o), stray_dentry(d), tid(t) { stray_dentry->get(CDentry::PIN_PURGING); + stray_dentry->reintegration_reqid = tid; } ~MDSMetaRequest() { + stray_dentry->reintegration_reqid = 0; stray_dentry->put(CDentry::PIN_PURGING); } diff --git a/src/mds/StrayManager.cc b/src/mds/StrayManager.cc index ab5844fa7b7f78..adcd30874830bb 100644 --- a/src/mds/StrayManager.cc +++ b/src/mds/StrayManager.cc @@ -595,7 +595,13 @@ void StrayManager::eval_remote(CDentry *remote_dn) CDentry *primary_dn = in->get_projected_parent_dn(); ceph_assert(primary_dn != NULL); if (primary_dn->get_dir()->get_inode()->is_stray()) { - _eval_stray_remote(primary_dn, remote_dn); + if (!primary_dn->reintegration_reqid) { + _eval_stray_remote(primary_dn, remote_dn); + } else { + dout(20) << __func__ + << ": inode's primary is already under reintegrating/migrating" + << dendl; + } } else { dout(20) << __func__ << ": inode's primary dn not stray" << dendl; }