From: sajibreadd Date: Thu, 9 Oct 2025 11:48:35 +0000 (+0200) Subject: mds: scrub pins more inodes than the mds_cache_memory_limit X-Git-Tag: testing/wip-vshankar-testing-20260222.101816^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=2aba0f8b95336f245ccfa7bf3d043ff0476f4525;p=ceph-ci.git 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 --- 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. *