]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: and 'force' options to scrub_path asok command
authorYan, Zheng <zyan@redhat.com>
Wed, 27 Jan 2016 10:06:08 +0000 (18:06 +0800)
committerYan, Zheng <zyan@redhat.com>
Mon, 7 Mar 2016 07:59:13 +0000 (15:59 +0800)
'force' means check whole subtree (don't skip scrubbing entries
not modified since last scrub)

Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/mds/CDir.cc
src/mds/CDir.h
src/mds/CInode.cc
src/mds/CInode.h
src/mds/MDCache.cc
src/mds/MDCache.h
src/mds/MDSDaemon.cc
src/mds/MDSRank.cc
src/mds/ScrubHeader.h
src/mds/ScrubStack.cc

index ec4b80ce31bdd2065985328717c9f74e1055d19e..045e5b3e0b4498a944d19606eead8ea73b591a55 100644 (file)
@@ -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<dentry_key_t>& 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;
index 3071d132304ce51be418c5d48a09b1fe958af0ce..81a1fa89d8aef7ea5491d28a9ef994098fc868fc 100644 (file)
@@ -264,6 +264,8 @@ public:
     set<dentry_key_t> others_scrubbing;
     set<dentry_key_t> 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
index c4b06dd71b89b4729d6218e22b9071abb393b837..8041c419dea922d39a12361e97f7e6fd31ecf1bb 100644 (file)
@@ -4164,7 +4164,10 @@ void CInode::scrub_initialize(CDentry *scrub_parent,
     for (std::list<frag_t>::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];
     }
   }
 
index 98af256f3c40c467be3af9c84c05be87d5dbaa88..5c7e3ea1445ddf3f879a03094569bf06d526dcb8 100644 (file)
@@ -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 {
index 9eb47f8b02ccf59dbd32208247f2975e89253824..9e670ff82c1acd742804720b570ecb6e73603588 100644 (file)
@@ -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;
index b6d1253dea90547710e61f86728ca1eb12340bc4..0994b77f92d93063f7f475e52dd04d7275c71e8a 100644 (file)
@@ -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);
 };
index 3451819382e41666e6740a019e1a31880a50eb97..1809c2d41734d789c1c64959e80bdb992c3fdc2d 100644 (file)
@@ -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);
index 7256fec47d26558a173daabea894f88b441b5d51..12d68b323cc15a55d654cc0424b8eced52873da9 100644 (file)
@@ -1878,10 +1878,13 @@ void MDSRankDispatcher::dump_sessions(const SessionFilter &filter, Formatter *f)
 
 void MDSRank::command_scrub_path(Formatter *f, const string& path, vector<string>& scrubop_vec)
 {
+  bool force = false;
   bool recursive = false;
   bool repair = false;
   for (vector<string>::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, vector<string
   C_SaferCond scond;
   {
     Mutex::Locker l(mds_lock);
-    mdcache->enqueue_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();
 }
index 3b7eadea23e608709ff8feb5384563ecd722d14a..72231b5888c78e89b2941903a87fc433e72db062 100644 (file)
@@ -16,6 +16,7 @@ public:
   CInode *origin;
   std::string tag;
 
+  bool force;
   bool recursive;
   bool repair;
   Formatter *formatter;
index 5ef567443d4a60bd4e65a2129cb9e48988c5664f..9dcb1a57a252cdf4ae667407db799ddf0540bbb7 100644 (file)
@@ -306,7 +306,7 @@ void ScrubStack::scrub_dirfrag(CDir *dir,
       return;
     }
 
-    dir->scrub_initialize();
+    dir->scrub_initialize(header);
   }
 
   int r = 0;