From 8e4bbb78bb04ddba829de35ae64fddd01f6b29fa Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Fri, 15 Sep 2023 08:41:35 +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 (cherry picked from commit 53d9e657e42bdf2440cd93a8273eb3ce79d8bd33) --- src/mds/CDentry.h | 2 ++ src/mds/StrayManager.cc | 30 ++++++++++++++++++++++++++---- src/mds/StrayManager.h | 17 ++++++++++++++++- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/mds/CDentry.h b/src/mds/CDentry.h index 6897f1749a2bb..3312c051b0a30 100644 --- a/src/mds/CDentry.h +++ b/src/mds/CDentry.h @@ -374,6 +374,8 @@ public: 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/StrayManager.cc b/src/mds/StrayManager.cc index 83ab85643b5c9..98764e243bd5d 100644 --- a/src/mds/StrayManager.cc +++ b/src/mds/StrayManager.cc @@ -672,24 +672,41 @@ void StrayManager::reintegrate_stray(CDentry *straydn, CDentry *rdn) { dout(10) << __func__ << " " << *straydn << " to " << *rdn << dendl; + if (straydn->reintegration_reqid) { + dout(20) << __func__ << ": stray dentry " << *straydn + << " is already under reintegrating" << dendl; + return; + } + logger->inc(l_mdc_strays_reintegrated); - + // rename it to remote linkage . filepath src(straydn->get_name(), straydn->get_dir()->ino()); filepath dst(rdn->get_name(), rdn->get_dir()->ino()); + ceph_tid_t tid = mds->issue_tid(); + auto req = make_message(CEPH_MDS_OP_RENAME); req->set_filepath(dst); req->set_filepath2(src); - req->set_tid(mds->issue_tid()); + req->set_tid(tid); + + auto ptr = std::make_unique(CEPH_MDS_OP_RENAME, tid, straydn); + mds->internal_client_requests.emplace(tid, std::move(ptr)); mds->send_message_mds(req, rdn->authority().first); } - + void StrayManager::migrate_stray(CDentry *dn, mds_rank_t to) { dout(10) << __func__ << " " << *dn << " to mds." << to << dendl; + if (dn->reintegration_reqid) { + dout(20) << __func__ << ": stray dentry " << *dn + << " is already under migrating" << dendl; + return; + } + logger->inc(l_mdc_strays_migrated); // rename it to another mds. @@ -699,10 +716,15 @@ void StrayManager::migrate_stray(CDentry *dn, mds_rank_t to) filepath src(dn->get_name(), dirino); filepath dst(dn->get_name(), MDS_INO_STRAY(to, MDS_INO_STRAY_INDEX(dirino))); + ceph_tid_t tid = mds->issue_tid(); + auto req = make_message(CEPH_MDS_OP_RENAME); req->set_filepath(dst); req->set_filepath2(src); - req->set_tid(mds->issue_tid()); + req->set_tid(tid); + + auto ptr = std::make_unique(CEPH_MDS_OP_RENAME, tid, dn); + mds->internal_client_requests.emplace(tid, std::move(ptr)); mds->send_message_mds(req, to); } diff --git a/src/mds/StrayManager.h b/src/mds/StrayManager.h index 86b6941a51313..874fbbb9a8dcd 100644 --- a/src/mds/StrayManager.h +++ b/src/mds/StrayManager.h @@ -19,15 +19,30 @@ #include #include "Mutation.h" #include "PurgeQueue.h" +#include "MDSMetaRequest.h" +#include "CDentry.h" class MDSRank; class CInode; -class CDentry; class StrayManager { // My public interface is for consumption by MDCache public: + struct StrayEvalRequest : public MDSMetaRequest { + CDentry *dentry; + public: + explicit StrayEvalRequest(int o, ceph_tid_t t, CDentry *d) : + MDSMetaRequest(o, t), dentry(d) { + dentry->get(CDentry::PIN_PURGING); + dentry->reintegration_reqid = t; + } + ~StrayEvalRequest() { + dentry->reintegration_reqid = 0; + dentry->put(CDentry::PIN_PURGING); + } + }; + explicit StrayManager(MDSRank *mds, PurgeQueue &purge_queue_); void set_logger(PerfCounters *l) {logger = l;} void activate(); -- 2.39.5