]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
mds/scrub: enqueue all child frags for a given fragset
authorMilind Changire <mchangir@redhat.com>
Tue, 26 Sep 2023 10:50:50 +0000 (16:20 +0530)
committerMilind Changire <mchangir@redhat.com>
Tue, 26 Sep 2023 10:50:50 +0000 (16:20 +0530)
Problem:
fragsets sent over to replicas for scrubbing are simplified i.e. they
are bit representation of the lease common ancestors of the frags that
need scrubbing on that replica. A search operation of a frag in the
frasget often fails to match exactly with the frags delegated to the
replica causing the scrub item to infinitely be held in the scrub stack.

Solution:
Test if the frag in the fragset sent over to the replica contains the
delegated frag as a child to accept it for scrubbing.

Fixes: https://tracker.ceph.com/issues/62658
Signed-off-by: Milind Changire <mchangir@redhat.com>
src/mds/ScrubStack.cc

index 6d799343f1496c2f7c0a414a67215d9185f1c0a2..047bf3ba82209ff65103dbfdb552c720b8a37223 100644 (file)
@@ -892,22 +892,30 @@ void ScrubStack::handle_scrub(const cref_t<MMDSScrub> &m)
 
       std::vector<CDir*> dfs;
       MDSGatherBuilder gather(g_ceph_context);
+      frag_vec_t frags;
+      diri->dirfragtree.get_leaves(frags);
       for (const auto& fg : m->get_frags()) {
-       CDir *dir = diri->get_dirfrag(fg);
-       if (!dir) {
-         dout(10) << __func__ << " no frag " << fg << dendl;
-         continue;
-       }
-       if (!dir->is_auth()) {
-         dout(10) << __func__ << " not auth " << *dir << dendl;
-         continue;
-       }
-       if (!dir->can_auth_pin()) {
-         dout(10) << __func__ << " can't auth pin " << *dir <<  dendl;
-         dir->add_waiter(CDir::WAIT_UNFREEZE, gather.new_sub());
-         continue;
+       for (auto f : frags) {
+         if (!fg.contains(f)) {
+           dout(20) << __func__ << " skipping " << f << dendl;
+           continue;
+         }
+         CDir *dir = diri->get_or_open_dirfrag(mdcache, f);
+         if (!dir) {
+           dout(10) << __func__ << " no frag " << f << dendl;
+           continue;
+         }
+         if (!dir->is_auth()) {
+           dout(10) << __func__ << " not auth " << *dir << dendl;
+           continue;
+         }
+         if (!dir->can_auth_pin()) {
+           dout(10) << __func__ << " can't auth pin " << *dir <<  dendl;
+           dir->add_waiter(CDir::WAIT_UNFREEZE, gather.new_sub());
+           continue;
+         }
+         dfs.push_back(dir);
        }
-       dfs.push_back(dir);
       }
 
       if (gather.has_subs()) {