]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
cephfs: Reset scrub data when inodes move
authorDouglas Fuller <dfuller@redhat.com>
Thu, 30 Nov 2017 16:13:36 +0000 (11:13 -0500)
committerPrashant D <pdhange@redhat.com>
Fri, 16 Feb 2018 05:41:32 +0000 (00:41 -0500)
If an inode currently on the ScrubStack is moved, it may be
initialized again, causing an assert. Instead, remove the inode
from its parent scrub list and reinitialize it.

Fixes: http://tracker.ceph.com/issues/22288
Signed-off-by: Douglas Fuller <dfuller@redhat.com>
(cherry picked from commit 4f5c8b604cc2a680652516e49e5a7cb4cbbbe887)

src/mds/CDir.cc
src/mds/CInode.cc

index 6796356b6bf1c09f5bd88faab03f75273a9f9da9..5fdc6987bf3da55c92882d580bac9c80309ed9f9 100644 (file)
@@ -3163,6 +3163,12 @@ int CDir::_next_dentry_on_set(set<dentry_key_t>& dns, bool missing_okay,
       continue;
     }
 
+    if (!dn->get_linkage()->is_primary()) {
+      dout(15) << " skip dentry " << dnkey.name
+              << ", no longer primary" << dendl;
+      continue;
+    }
+
     *dnout = dn;
     return 0;
   }
index dde1a47c633bb787d506b8200b021874641dffc3..c77ec80aa6243c33a4ec4f2e69a0db4f5b785058 100644 (file)
@@ -4349,7 +4349,17 @@ void CInode::scrub_initialize(CDentry *scrub_parent,
                              MDSInternalContextBase *f)
 {
   dout(20) << __func__ << " with scrub_version " << get_version() << dendl;
-  assert(!scrub_is_in_progress());
+  if (scrub_is_in_progress()) {
+    dout(20) << __func__ << " inode moved during scrub, reinitializing "
+            << dendl;
+    assert(scrub_infop->scrub_parent);
+    CDentry *dn = scrub_infop->scrub_parent;
+    CDir *dir = dn->dir;
+    dn->put(CDentry::PIN_SCRUBPARENT);
+    assert(dir->scrub_infop && dir->scrub_infop->directory_scrubbing);
+    dir->scrub_infop->directories_scrubbing.erase(dn->key());
+    dir->scrub_infop->others_scrubbing.erase(dn->key());
+  }
   scrub_info();
   if (!scrub_infop)
     scrub_infop = new scrub_info_t();