From 2aba0f8b95336f245ccfa7bf3d043ff0476f4525 Mon Sep 17 00:00:00 2001 From: sajibreadd Date: Thu, 9 Oct 2025 13:48:35 +0200 Subject: [PATCH] mds: scrub pins more inodes than the mds_cache_memory_limit For scrubbing dirfrag we are pushing children back into the scrub stack. Instead we can follow the same strategy for scrub directory and pushing children front of the scrub stack, and in kick_off_scrubs always start scrubbing from the front of the stack. It will prevent ScrubStack to pinning whole level of the file-system tree. Fixes: https://tracker.ceph.com/issues/71167 Signed-off-by: Md Mahamudur Rahaman Sajib --- src/mds/ScrubStack.cc | 21 +++++++++++---------- src/mds/ScrubStack.h | 3 ++- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/mds/ScrubStack.cc b/src/mds/ScrubStack.cc index 2cb83b15748..efe0d3ed042 100644 --- a/src/mds/ScrubStack.cc +++ b/src/mds/ScrubStack.cc @@ -308,16 +308,16 @@ void ScrubStack::kick_off_scrubs() } } } else if (CDir *dir = dynamic_cast(*it)) { - auto next = it; - ++next; + ++it; + bool added_children = false; bool done = false; // it's done, so pop it off the stack - scrub_dirfrag(dir, &done); + scrub_dirfrag(dir, &added_children, &done); if (done) { - dout(20) << __func__ << " dirfrag, done" << dendl; - ++it; // child inodes were queued at bottom of stack - dequeue(dir); - } else { - it = next; + dout(20) << __func__ << " dirfrag, done" << dendl; + dequeue(dir); + } + if (added_children) { + it = scrub_stack.begin(); } } else { ceph_assert(0 == "dentry in scrub stack"); @@ -501,7 +501,7 @@ void ScrubStack::identify_remote_link_damage(CDentry *dn) { } } -void ScrubStack::scrub_dirfrag(CDir *dir, bool *done) +void ScrubStack::scrub_dirfrag(CDir *dir, bool *added_children, bool *done) { ceph_assert(dir != NULL); @@ -540,7 +540,8 @@ void ScrubStack::scrub_dirfrag(CDir *dir, bool *done) continue; } if (dnl->is_primary()) { - _enqueue(dnl->get_inode(), header, false); + *added_children = true; + _enqueue(dnl->get_inode(), header, true); } else if (dnl->is_remote() || dnl->is_referent_remote()) { identify_remote_link_damage(dn); } diff --git a/src/mds/ScrubStack.h b/src/mds/ScrubStack.h index f5e4c736793..f922258edd8 100644 --- a/src/mds/ScrubStack.h +++ b/src/mds/ScrubStack.h @@ -242,9 +242,10 @@ private: * scrub of the dirfrag. * * @param dir The dirfrag to scrub (must be auth) + * @param added_children set to true if we pushed some of our children * @param done set to true if we started to do final scrub */ - void scrub_dirfrag(CDir *dir, bool *done); + void scrub_dirfrag(CDir *dir, bool *added_children, bool *done); /** * Scrub a directory-representing dentry. * -- 2.47.3