From: Yan, Zheng Date: Fri, 11 Dec 2015 13:56:15 +0000 (+0800) Subject: mds: and 'recursive/repair' options to scrub_path asok command X-Git-Tag: v10.1.0~176^2~1^2~14 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=2a671521fc0e07a14f98ccdef0cef2a6b07a990b;p=ceph.git mds: and 'recursive/repair' options to scrub_path asok command Signed-off-by: Yan, Zheng --- diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index f49970046e3..ec4b80ce31b 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -3088,7 +3088,9 @@ bool CDir::scrub_local() scrub_infop->last_local.time = ceph_clock_now(g_ceph_context); scrub_infop->last_local.version = get_projected_version(); scrub_infop->last_scrub_dirty = true; - } else { + } else if (inode->scrub_infop && + inode->scrub_infop->header && + inode->scrub_infop->header->repair) { cache->repair_dirfrag_stats(this, NULL); } return rval; diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 52ff4827db5..ad4ee4529ea 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -3942,7 +3942,10 @@ next: !nest_info.same_sums(in->inode.rstat)) { results->raw_stats.error_str << "freshly-calculated rstats don't match existing ones"; - in->mdcache->repair_inode_stats(in, NULL); + if (in->scrub_infop && + in->scrub_infop->header && + in->scrub_infop->header->repair) + in->mdcache->repair_inode_stats(in, NULL); goto next; } results->raw_stats.passed = true; diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 2626ec08940..bdadc6d1f71 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -11707,7 +11707,7 @@ public: void MDCache::enqueue_scrub( const string& path, const std::string &tag, - bool recursive, + bool recursive, bool repair, Formatter *f, Context *fin) { dout(10) << __func__ << path << dendl; @@ -11719,6 +11719,7 @@ void MDCache::enqueue_scrub( ScrubHeaderRef &header = cs->header; header->tag = tag; header->recursive = recursive; + header->repair = repair; header->formatter = f; mdr->internal_op_finish = cs; diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h index 30a382a49c1..b6d1253dea9 100644 --- a/src/mds/MDCache.h +++ b/src/mds/MDCache.h @@ -1149,7 +1149,7 @@ public: * Create and start an OP_ENQUEUE_SCRUB */ void enqueue_scrub(const string& path, const std::string &tag, - bool recursive, Formatter *f, Context *fin); + bool recursive, bool repair, Formatter *f, Context *fin); void repair_inode_stats(CInode *diri, Context *fin); void repair_dirfrag_stats(CDir *dir, Context *fin); }; diff --git a/src/mds/MDSDaemon.cc b/src/mds/MDSDaemon.cc index 6a50659b48f..3451819382e 100644 --- a/src/mds/MDSDaemon.cc +++ b/src/mds/MDSDaemon.cc @@ -246,7 +246,8 @@ void MDSDaemon::set_up_admin_socket() "show slowest recent ops"); assert(r == 0); r = admin_socket->register_command("scrub_path", - "scrub_path name=path,type=CephString", + "scrub_path name=path,type=CephString " + "name=scrubops,type=CephChoices,strings=recursive|repair,n=N,req=false", asok_hook, "scrub an inode and output results"); assert(r == 0); diff --git a/src/mds/MDSRank.cc b/src/mds/MDSRank.cc index 42315fffece..7256fec47d2 100644 --- a/src/mds/MDSRank.cc +++ b/src/mds/MDSRank.cc @@ -1734,8 +1734,10 @@ bool MDSRankDispatcher::handle_asok_command( } } else if (command == "scrub_path") { string path; + vector scrubop_vec; + cmd_getval(g_ceph_context, cmdmap, "scrubops", scrubop_vec); cmd_getval(g_ceph_context, cmdmap, "path", path); - command_scrub_path(f, path); + command_scrub_path(f, path, scrubop_vec); } else if (command == "tag path") { string path; cmd_getval(g_ceph_context, cmdmap, "path", path); @@ -1874,12 +1876,20 @@ void MDSRankDispatcher::dump_sessions(const SessionFilter &filter, Formatter *f) f->close_section(); //sessions } -void MDSRank::command_scrub_path(Formatter *f, const string& path) +void MDSRank::command_scrub_path(Formatter *f, const string& path, vector& scrubop_vec) { + bool recursive = false; + bool repair = false; + for (vector::iterator i = scrubop_vec.begin() ; i != scrubop_vec.end(); ++i) { + if (*i == "recursive") + recursive = true; + else if (*i == "repair") + repair = true; + } C_SaferCond scond; { Mutex::Locker l(mds_lock); - mdcache->enqueue_scrub(path, "", false, f, &scond); + mdcache->enqueue_scrub(path, "", recursive, repair, f, &scond); } scond.wait(); // scrub_dentry() finishers will dump the data for us; we're done! @@ -1891,7 +1901,7 @@ void MDSRank::command_tag_path(Formatter *f, C_SaferCond scond; { Mutex::Locker l(mds_lock); - mdcache->enqueue_scrub(path, tag, true, f, &scond); + mdcache->enqueue_scrub(path, tag, true, false, f, &scond); } scond.wait(); } diff --git a/src/mds/MDSRank.h b/src/mds/MDSRank.h index a11f3b943ea..e4f4f1dfe28 100644 --- a/src/mds/MDSRank.h +++ b/src/mds/MDSRank.h @@ -364,7 +364,7 @@ class MDSRank { protected: void dump_clientreplay_status(Formatter *f) const; - void command_scrub_path(Formatter *f, const string& path); + void command_scrub_path(Formatter *f, const string& path, vector& scrubop_vec); void command_tag_path(Formatter *f, const string& path, const string &tag); void command_flush_path(Formatter *f, const string& path); diff --git a/src/mds/ScrubHeader.h b/src/mds/ScrubHeader.h index 46783ed680f..35d355695e3 100644 --- a/src/mds/ScrubHeader.h +++ b/src/mds/ScrubHeader.h @@ -17,6 +17,7 @@ public: std::string tag; bool recursive; + bool repair; Formatter *formatter; }; typedef ceph::shared_ptr ScrubHeaderRef; diff --git a/src/mds/ScrubStack.cc b/src/mds/ScrubStack.cc index f99b3ed6035..158d6735d1f 100644 --- a/src/mds/ScrubStack.cc +++ b/src/mds/ScrubStack.cc @@ -227,11 +227,6 @@ 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) { - scrubs_in_progress++; - dn->scrub_set_finisher(&scrub_kick); - } - // 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 @@ -301,6 +296,11 @@ void ScrubStack::scrub_dir_dentry_final(CDentry *dn) // FIXME: the magic-constructing scrub_info() is going to leave // an unneeded scrub_infop lying around here if (!dn->scrub_info()->dentry_children_done) { + if (!dn->scrub_info()->on_finish) { + scrubs_in_progress++; + dn->scrub_set_finisher(&scrub_kick); + } + dn->scrub_children_finished(); CInode *in = dn->get_projected_inode(); C_InodeValidated *fin = new C_InodeValidated(mdcache->mds, this, dn);