From: Douglas Fuller Date: Thu, 30 Nov 2017 16:13:36 +0000 (-0500) Subject: cephfs: Reset scrub data when inodes move X-Git-Tag: v13.0.2~279^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=4f5c8b604cc2a680652516e49e5a7cb4cbbbe887;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 --- diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index 97d9c3fe85f69..5d530603fdb25 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -3185,6 +3185,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 412a4f3d59e9a..829572587825f 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -4417,7 +4417,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();