From: Douglas Fuller Date: Thu, 30 Nov 2017 16:13:36 +0000 (-0500) Subject: cephfs: Reset scrub data when inodes move X-Git-Tag: v12.2.5~107^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=b80738c1933e2cadbabb106f9e335c9848e9d444;p=ceph.git cephfs: Reset scrub data when inodes move 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 (cherry picked from commit 4f5c8b604cc2a680652516e49e5a7cb4cbbbe887) --- diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index 6796356b6bf..5fdc6987bf3 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -3163,6 +3163,12 @@ int CDir::_next_dentry_on_set(set& 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; } diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index dde1a47c633..c77ec80aa62 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -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();