From: Yan, Zheng Date: Tue, 10 Nov 2015 12:42:20 +0000 (+0800) Subject: mds: call CDentry::scrub_finished() when skipping special dentry X-Git-Tag: v10.0.1~51^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=6e370bbf1a59a55130fde0caeac983f49908fc58;p=ceph.git mds: call CDentry::scrub_finished() when skipping special dentry Also set the on finish context when starting scrub a dentry, this avoids deleting context for skipped dentry. Signed-off-by: Yan, Zheng --- diff --git a/src/mds/CDentry.h b/src/mds/CDentry.h index 81f0e38ddf16..171fb3b1c0fd 100644 --- a/src/mds/CDentry.h +++ b/src/mds/CDentry.h @@ -186,6 +186,9 @@ public: void scrub_children_finished() { scrub_infop->dentry_children_done = true; } + void scrub_set_finisher(Context *c) { + scrub_infop->on_finish = c; + } private: /** diff --git a/src/mds/ScrubStack.cc b/src/mds/ScrubStack.cc index 948154f33034..a9480818faff 100644 --- a/src/mds/ScrubStack.cc +++ b/src/mds/ScrubStack.cc @@ -100,12 +100,17 @@ void ScrubStack::kick_off_scrubs() pop_dentry(cur); // we only touch it this once, so remove from stack if (curi->is_file()) { + if (!cur->scrub_info()->on_finish) + cur->scrub_set_finisher(new C_KickOffScrubs(mdcache->mds, this)); scrub_file_dentry(cur); can_continue = true; } else { // drat, we don't do anything with these yet :( dout(5) << "skipping scrub on non-dir, non-file dentry " << *cur << dendl; + Context *c = NULL; + cur->scrub_finished(&c); + assert(c == NULL); } } else { bool completed; // it's done, so pop it off the stack @@ -223,6 +228,9 @@ void ScrubStack::scrub_dir_dentry(CDentry *dn, if (all_frags_done) { assert (!*added_children); // can't do this if children are still pending + if (!dn->scrub_info()->on_finish) + dn->scrub_set_finisher(new C_KickOffScrubs(mdcache->mds, this)); + // OK, so now I can... fire off a validate on the dir inode, and // when it completes, come through here again, noticing that we've // set a flag to indicate the the validate happened, and @@ -378,13 +386,12 @@ void ScrubStack::scrub_dirfrag(CDir *dir, bool *added_children, // FIXME: Do I *really* need to construct a kick context for every // single dentry I'm going to scrub? - MDSInternalContext *on_d_scrub = new C_KickOffScrubs(mdcache->mds, this); _enqueue_dentry(dn, dir, parent_dn->scrub_info()->scrub_recursive, false, // We are already recursing so scrub_children not meaningful header, - on_d_scrub, + NULL, true); *added_children = true;