]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
mds: scrub pins more inodes than the mds_cache_memory_limit
authorsajibreadd <sajibreadd@gmail.com>
Thu, 9 Oct 2025 11:48:35 +0000 (13:48 +0200)
committersajibreadd <sajibreadd@gmail.com>
Thu, 11 Dec 2025 06:26:35 +0000 (07:26 +0100)
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 <mahamudur.sajib@croit.io>
src/mds/ScrubStack.cc
src/mds/ScrubStack.h

index 2cb83b1574813ba540f0f4f880dd6acc8e9b9e30..efe0d3ed042572d9196f59fe3ae701ae7b70a8d9 100644 (file)
@@ -308,16 +308,16 @@ void ScrubStack::kick_off_scrubs()
        }
       }
     } else if (CDir *dir = dynamic_cast<CDir*>(*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);
       }
index f5e4c736793c9797f1ad5fc676f570b1596f0584..f922258edd8468a7febd80285d493fc769e5c875 100644 (file)
@@ -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.
    *