From: Yan, Zheng Date: Wed, 27 Jan 2016 10:06:08 +0000 (+0800) Subject: mds: and 'force' options to scrub_path asok command X-Git-Tag: v10.1.0~176^2~1^2~10 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=72b9339e96759369383ed1d6f58ed05292d1bdb1;p=ceph.git mds: and 'force' options to scrub_path asok command 'force' means check whole subtree (don't skip scrubbing entries not modified since last scrub) Signed-off-by: Yan, Zheng --- diff --git a/src/mds/CDir.cc b/src/mds/CDir.cc index ec4b80ce31b..045e5b3e0b4 100644 --- a/src/mds/CDir.cc +++ b/src/mds/CDir.cc @@ -2897,7 +2897,7 @@ void CDir::scrub_info_create() const me->scrub_infop = si; } -void CDir::scrub_initialize() +void CDir::scrub_initialize(const ScrubHeaderRefConst& header) { dout(20) << __func__ << dendl; assert(is_complete()); @@ -2935,6 +2935,7 @@ void CDir::scrub_initialize() } } scrub_infop->directory_scrubbing = true; + scrub_infop->header = header; } void CDir::scrub_finished() @@ -2986,7 +2987,8 @@ int CDir::_next_dentry_on_set(set& dns, bool missing_okay, // okay, we got a dentry dns.erase(dnkey); - if (dn->get_projected_version() < scrub_infop->last_recursive.version) { + if (dn->get_projected_version() < scrub_infop->last_recursive.version && + !(scrub_infop->header && scrub_infop->header->force)) { dout(15) << " skip dentry " << dnkey.name << ", no change since last scrub" << dendl; continue; @@ -3088,9 +3090,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 if (inode->scrub_infop && - inode->scrub_infop->header && - inode->scrub_infop->header->repair) { + } else if (scrub_infop && + scrub_infop->header && + scrub_infop->header->repair) { cache->repair_dirfrag_stats(this, NULL); } return rval; diff --git a/src/mds/CDir.h b/src/mds/CDir.h index 3071d132304..81a1fa89d8a 100644 --- a/src/mds/CDir.h +++ b/src/mds/CDir.h @@ -264,6 +264,8 @@ public: set others_scrubbing; set others_scrubbed; + ScrubHeaderRefConst header; + scrub_info_t() : directory_scrubbing(false), need_scrub_local(false), last_scrub_dirty(false) {} @@ -274,7 +276,7 @@ public: * @pre The CDir is marked complete. * @post It has set up its internal scrubbing state. */ - void scrub_initialize(); + void scrub_initialize(const ScrubHeaderRefConst& header); /** * Get the next dentry to scrub. Gives you a CDentry* and its meaning. This * function will give you all directory-representing dentries before any diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index c4b06dd71b8..8041c419dea 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -4164,7 +4164,10 @@ void CInode::scrub_initialize(CDentry *scrub_parent, for (std::list::iterator i = frags.begin(); i != frags.end(); ++i) { - scrub_infop->dirfrag_stamps[*i]; + if (header->force) + scrub_infop->dirfrag_stamps[*i].reset(); + else + scrub_infop->dirfrag_stamps[*i]; } } diff --git a/src/mds/CInode.h b/src/mds/CInode.h index 98af256f3c4..5c7e3ea1445 100644 --- a/src/mds/CInode.h +++ b/src/mds/CInode.h @@ -257,6 +257,10 @@ public: /// time we started our most recent finished scrub utime_t last_scrub_stamp; scrub_stamp_info_t() : scrub_start_version(0), last_scrub_version(0) {} + void reset() { + scrub_start_version = 0; + scrub_start_stamp = utime_t(); + } }; class scrub_info_t : public scrub_stamp_info_t { diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 9eb47f8b02c..9e670ff82c1 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 repair, + bool force, bool recursive, bool repair, Formatter *f, Context *fin) { dout(10) << __func__ << path << dendl; @@ -11718,6 +11718,7 @@ void MDCache::enqueue_scrub( C_MDS_EnqueueScrub *cs = new C_MDS_EnqueueScrub(f, fin); ScrubHeaderRef &header = cs->header; header->tag = tag; + header->force = force; header->recursive = recursive; header->repair = repair; header->formatter = f; diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h index b6d1253dea9..0994b77f92d 100644 --- a/src/mds/MDCache.h +++ b/src/mds/MDCache.h @@ -1149,7 +1149,8 @@ public: * Create and start an OP_ENQUEUE_SCRUB */ void enqueue_scrub(const string& path, const std::string &tag, - bool recursive, bool repair, Formatter *f, Context *fin); + bool force, 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 3451819382e..1809c2d4173 100644 --- a/src/mds/MDSDaemon.cc +++ b/src/mds/MDSDaemon.cc @@ -247,7 +247,8 @@ void MDSDaemon::set_up_admin_socket() assert(r == 0); r = admin_socket->register_command("scrub_path", "scrub_path name=path,type=CephString " - "name=scrubops,type=CephChoices,strings=recursive|repair,n=N,req=false", + "name=scrubops,type=CephChoices," + "strings=force|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 7256fec47d2..12d68b323cc 100644 --- a/src/mds/MDSRank.cc +++ b/src/mds/MDSRank.cc @@ -1878,10 +1878,13 @@ void MDSRankDispatcher::dump_sessions(const SessionFilter &filter, Formatter *f) void MDSRank::command_scrub_path(Formatter *f, const string& path, vector& scrubop_vec) { + bool force = false; bool recursive = false; bool repair = false; for (vector::iterator i = scrubop_vec.begin() ; i != scrubop_vec.end(); ++i) { - if (*i == "recursive") + if (*i == "force") + force = true; + else if (*i == "recursive") recursive = true; else if (*i == "repair") repair = true; @@ -1889,7 +1892,7 @@ void MDSRank::command_scrub_path(Formatter *f, const string& path, vectorenqueue_scrub(path, "", recursive, repair, f, &scond); + mdcache->enqueue_scrub(path, "", force, recursive, repair, f, &scond); } scond.wait(); // scrub_dentry() finishers will dump the data for us; we're done! @@ -1901,7 +1904,7 @@ void MDSRank::command_tag_path(Formatter *f, C_SaferCond scond; { Mutex::Locker l(mds_lock); - mdcache->enqueue_scrub(path, tag, true, false, f, &scond); + mdcache->enqueue_scrub(path, tag, true, true, false, f, &scond); } scond.wait(); } diff --git a/src/mds/ScrubHeader.h b/src/mds/ScrubHeader.h index 3b7eadea23e..72231b5888c 100644 --- a/src/mds/ScrubHeader.h +++ b/src/mds/ScrubHeader.h @@ -16,6 +16,7 @@ public: CInode *origin; std::string tag; + bool force; bool recursive; bool repair; Formatter *formatter; diff --git a/src/mds/ScrubStack.cc b/src/mds/ScrubStack.cc index 5ef567443d4..9dcb1a57a25 100644 --- a/src/mds/ScrubStack.cc +++ b/src/mds/ScrubStack.cc @@ -306,7 +306,7 @@ void ScrubStack::scrub_dirfrag(CDir *dir, return; } - dir->scrub_initialize(); + dir->scrub_initialize(header); } int r = 0;