]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: implement ScrubHeader
authorJohn Spray <john.spray@redhat.com>
Wed, 15 Jul 2015 16:24:07 +0000 (17:24 +0100)
committerYan, Zheng <zyan@redhat.com>
Wed, 4 Nov 2015 09:17:25 +0000 (17:17 +0800)
A place for scrubbed dentries to learn about the params
that started the scrub off, such as the tag.

Signed-off-by: John Spray <john.spray@redhat.com>
src/mds/CDentry.cc
src/mds/CDentry.h
src/mds/MDCache.cc
src/mds/MDCache.h
src/mds/MDSDaemon.cc
src/mds/MDSRank.cc
src/mds/MDSRank.h
src/mds/Makefile-server.am
src/mds/ScrubHeader.h [new file with mode: 0644]
src/mds/ScrubStack.cc
src/mds/ScrubStack.h

index d40b5a02574b8d7f6dbfb25e6ead908dddb9257a..f241b81b693275a3c9788bb04465a4a958726681 100644 (file)
@@ -623,6 +623,7 @@ std::string CDentry::linkage_t::get_remote_d_type_string() const
 }
 
 void CDentry::scrub_initialize(CDir *parent, bool recurse, bool children,
+                        ScrubHeaderRefConst header,
                                Context *f)
 {
   if (!scrub_infop)
@@ -635,6 +636,7 @@ void CDentry::scrub_initialize(CDir *parent, bool recurse, bool children,
   scrub_infop->scrub_children = children;
   scrub_infop->dentry_scrubbing = true;
   scrub_infop->on_finish = f;
+  scrub_infop->header = header;
 
   auth_pin(this);
 }
@@ -650,6 +652,14 @@ void CDentry::scrub_finished(Context **c)
 
   *c = scrub_infop->on_finish;
 
+  if (scrub_infop->header && scrub_infop->header->origin == this) {
+    // We are at the point that a tagging scrub was initiated
+    LogChannelRef clog = dir->cache->mds->clog;
+    clog->info() << "scrub complete with tag '"
+      << scrub_infop->header->tag << "'";
+    
+  }
+
   delete scrub_infop;
   scrub_infop = NULL;
 
index 7470ff4db6adae918974aa1201184d881e79d865..ee133384372f50b50f21fbd797b905761850a869 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "SimpleLock.h"
 #include "LocalLock.h"
+#include "ScrubHeader.h"
 
 class CInode;
 class CDir;
@@ -147,6 +148,8 @@ public:
     bool scrub_children; /// true if we have to scrub all direct children
     bool dentry_scrubbing; /// safety check
     Context *on_finish; /// called when we finish scrubbing
+    ScrubHeaderRefConst header;
+
     scrub_info_t() :
       scrub_parent(NULL), scrub_recursive(false),
       scrub_children(false), dentry_scrubbing(false), on_finish(NULL)
@@ -173,6 +176,7 @@ public:
     return scrub_infop;
   }
   void scrub_initialize(CDir *parent, bool recurse, bool children,
+                        ScrubHeaderRefConst header,
                         Context *f);
   void scrub_finished(Context **c);
 
index bf654735214ae82beff4dcacf15bc5c672bc7eb4..e7889793f5c710ac7cf5e2e3c65e84cf377c6c91 100644 (file)
@@ -11739,7 +11739,10 @@ public:
   }
 };
 
-void MDCache::enqueue_scrub(const string& path, Formatter *f, Context *fin)
+void MDCache::enqueue_scrub(
+    const string& path,
+    const std::string &tag,
+    Formatter *f, Context *fin)
 {
   dout(10) << "scrub_dentry " << path << dendl;
   MDRequestRef mdr = request_start_internal(CEPH_MDS_OP_ENQUEUE_SCRUB);
@@ -11749,7 +11752,7 @@ void MDCache::enqueue_scrub(const string& path, Formatter *f, Context *fin)
   C_ScrubEnqueued *se = new C_ScrubEnqueued(mdr, fin, f);
   mdr->internal_op_finish = se;
   // TODO pass through tag/args
-  mdr->internal_op_private = new EnqueueScrubParams(true, true, "foobar");
+  mdr->internal_op_private = new EnqueueScrubParams(true, true, tag);
   enqueue_scrub_work(mdr);
 }
 
@@ -11784,7 +11787,12 @@ void MDCache::enqueue_scrub_work(MDRequestRef& mdr)
     return;
   }
 
-  mds->scrubstack->enqueue_dentry_bottom(dn, true, true, args->tag, NULL);
+  ScrubHeaderRef header(new ScrubHeader());
+
+  header->tag = args->tag;
+  header->origin = dn;
+
+  mds->scrubstack->enqueue_dentry_bottom(dn, true, true, header, NULL);
   delete args;
   mdr->internal_op_private = NULL;
 
index 3158b9cc7a8f78a94afe772cde796281af62da8c..93eb697f410244d4c0878818ef9b877921b82944 100644 (file)
@@ -1128,7 +1128,8 @@ public:
   /**
    * Create and start an OP_ENQUEUE_SCRUB
    */
-  void enqueue_scrub(const string& path, Formatter *f, Context *fin);
+  void enqueue_scrub(const string& path, const std::string &tag,
+                     Formatter *f, Context *fin);
 
   /**
    * Resolve path to a dentry and pass it onto the ScrubStack.
index 7f7def1361d6122057967845871255fcb320d41f..4109891af33d0457d505974ea370e38fda545ac5 100644 (file)
@@ -236,6 +236,12 @@ void MDSDaemon::set_up_admin_socket()
                                      asok_hook,
                                      "scrub an inode and output results");
   assert(r == 0);
+  r = admin_socket->register_command("tag path",
+                                     "tag path name=path,type=CephString"
+                                     " name=tag,type=CephString",
+                                     asok_hook,
+                                     "Apply scrub tag recursively");
+   assert(r == 0);
   r = admin_socket->register_command("flush_path",
                                      "flush_path name=path,type=CephString",
                                      asok_hook,
index 85ca8b158e8b75fbdfc47f76e91912c546a87c23..1f0619ddd60c5b4e33a7a651c2fb7ba7eacb0c78 100644 (file)
@@ -1718,7 +1718,9 @@ bool MDSRankDispatcher::handle_asok_command(
   } else if (command == "tag path") {
     string path;
     cmd_getval(g_ceph_context, cmdmap, "path", path);
-    command_tag_path(f, path);
+    string tag;
+    cmd_getval(g_ceph_context, cmdmap, "tag", tag);
+    command_tag_path(f, path, tag);
   } else if (command == "flush_path") {
     string path;
     cmd_getval(g_ceph_context, cmdmap, "path", path);
@@ -1858,12 +1860,13 @@ void MDSRank::command_scrub_path(Formatter *f, const string& path)
   // scrub_dentry() finishers will dump the data for us; we're done!
 }
 
-void MDSRank::command_tag_path(Formatter *f, const string& path)
+void MDSRank::command_tag_path(Formatter *f,
+    const string& path, const std::string &tag)
 {
   C_SaferCond scond;
   {
     Mutex::Locker l(mds_lock);
-    mdcache->enqueue_scrub(path, f, &scond);
+    mdcache->enqueue_scrub(path, tag, f, &scond);
   }
   scond.wait();
 }
index 237b7368e1192821dced4706ffb821da7a4dee0f..8d2667b15bae022e62ba19848e3080da10710b42 100644 (file)
@@ -368,7 +368,8 @@ class MDSRank {
 
   protected:
     void command_scrub_path(Formatter *f, const string& path);
-    void command_tag_path(Formatter *f, const string& path);
+    void command_tag_path(Formatter *f, const string& path,
+                          const string &tag);
     void command_flush_path(Formatter *f, const string& path);
     void command_flush_journal(Formatter *f);
     void command_get_subtrees(Formatter *f);
index 1de7c5465ead37381c200bd44550298a63b0dce4..951bb8907cb462df2f9e6eced84aea6313d41e0a 100644 (file)
@@ -37,6 +37,7 @@ noinst_HEADERS += \
        mds/Migrator.h \
        mds/ScatterLock.h \
        mds/ScrubStack.h \
+       mds/ScrubHeader.h \
        mds/Server.h \
        mds/SessionMap.h \
        mds/SimpleLock.h \
diff --git a/src/mds/ScrubHeader.h b/src/mds/ScrubHeader.h
new file mode 100644 (file)
index 0000000..288f3a3
--- /dev/null
@@ -0,0 +1,23 @@
+
+#ifndef SCRUB_HEADER_H_
+#define SCRUB_HEADER_H_
+
+class CDentry;
+
+/**
+ * Externally input parameters for a scrub, associated with the root
+ * of where we are doing a recursive scrub
+ *
+ * TODO: swallow up 'recurse' and 'children' settings here instead of
+ * passing them down into every scrub_info structure
+ */
+class ScrubHeader {
+public:
+  std::string tag;
+  CDentry *origin;
+};
+typedef ceph::shared_ptr<ScrubHeader> ScrubHeaderRef;
+typedef ceph::shared_ptr<const ScrubHeader> ScrubHeaderRefConst;
+
+#endif // SCRUB_HEADER_H_
+
index 67029c6bb922181a6aa1e6dc63e75b6067b78f79..c5abc86d44d839b2be4f4c18f7171c5f400ba0c4 100644 (file)
@@ -58,14 +58,14 @@ void ScrubStack::pop_dentry(CDentry *dn)
 }
 
 void ScrubStack::_enqueue_dentry(CDentry *dn, CDir *parent, bool recursive,
-    bool children, const std::string &tag,
+    bool children, ScrubHeaderRefConst header,
     MDSInternalContextBase *on_finish, bool top)
 {
   dout(10) << __func__ << " with {" << *dn << "}"
            << ", recursive=" << recursive << ", children=" << children
            << ", on_finish=" << on_finish << ", top=" << top << dendl;
   assert(mdcache->mds->mds_lock.is_locked_by_me());
-  dn->scrub_initialize(parent, recursive, children, on_finish);
+  dn->scrub_initialize(parent, recursive, children, header, on_finish);
   if (top)
     push_dentry(dn);
   else
@@ -73,10 +73,10 @@ void ScrubStack::_enqueue_dentry(CDentry *dn, CDir *parent, bool recursive,
 }
 
 void ScrubStack::enqueue_dentry(CDentry *dn, bool recursive, bool children,
-                                const std::string &tag,
+                                ScrubHeaderRefConst header,
                                  MDSInternalContextBase *on_finish, bool top)
 {
-  _enqueue_dentry(dn, NULL, recursive, children, tag, on_finish, top);
+  _enqueue_dentry(dn, NULL, recursive, children, header, on_finish, top);
   kick_off_scrubs();
 }
 
@@ -348,72 +348,23 @@ void ScrubStack::scrub_dirfrag(CDir *dir, bool *added_children,
     // never get random IO errors here.
     assert(r == 0);
 
+
+    CDentry *parent_dn = dir->get_inode()->get_parent_dn();
+    ScrubHeaderRefConst header = parent_dn->scrub_info()->header;
+
     // 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,
-        /*
-         * FIXME: look up params from dir's inode's parent
-         */
-#if 0
-        dir->scrub_info()->scrub_recursive,
-        dir->scrub_info()->scrub_children,
-#else
-        true,
-        true,
-#endif
-        // FIXME: carry tag through
-        "foobar",
+        parent_dn->scrub_info()->scrub_recursive,
+        false,  // We are already recursing so scrub_children not meaningful
+        header,
         on_d_scrub,
         true);
 
     *added_children = true;
   }
-
-#if 0
-  bool any_unscrubbed = false;
-
-  for (CDir::map_t::iterator i = dir->begin(); i != dir->end(); ++ i) {
-    CDentry *dn = i->second;
-
-    if (dir->scrub_info()->directories_scrubbed.count(i->first) == 0
-        && dir->scrub_info()->others_scrubbed.count(i->first) == 0) {
-      dout(20) << __func__ << " dn not yet scrubbed: " << *dn << dendl;
-      any_unscrubbed = true;
-    }
-
-    if (dn->scrub_info()->dentry_scrubbing
-      ||  dir->scrub_info()->directories_scrubbed.count(i->first)
-      || dir->scrub_info()->others_scrubbed.count(i->first)) {
-      dout(20) << __func__ << " skipping already scrubbing or scrubbed " << *dn << dendl;
-      continue;
-    }
-
-    C_KickOffScrubs *c = new C_KickOffScrubs(mdcache->mds, this);
-
-    _enqueue_dentry(dn,
-        dir,
-        /*
-         * FIXME: look up params from dir's inode's parent
-         */
-#if 0
-        dir->scrub_info()->scrub_recursive,
-        dir->scrub_info()->scrub_children,
-#else
-        true,
-        true,
-#endif
-        // FIXME: carry tag through
-        "foobar",
-        c,
-        true);
-
-    *added_children = true;
-  }
-
-  *done = !any_unscrubbed;
-#endif
 }
 
 void ScrubStack::scrub_file_dentry(CDentry *dn)
index 0be512646d705349d37ecd2f672fd9db9f69753c..14ae869be5a7a1b98724b1f9568c7f9d1cadf242 100644 (file)
@@ -19,6 +19,7 @@
 #include "CDentry.h"
 #include "CInode.h"
 #include "MDSContext.h"
+#include "ScrubHeader.h"
 
 #include "include/elist.h"
 
@@ -59,20 +60,21 @@ public:
    * @param children True if we want to scrub the direct children of
    * dn but aren't doing a recursive scrub. (Otherwise, all checks are
    * local to dn's disk state.)
-   * @param tag If non-empty, tag applied to each verified rados object
+   * @param header The ScrubHeader propagated from whereever this scrub
+   *               was initiated
    */
   void enqueue_dentry_top(CDentry *dn, bool recursive, bool children,
-                          const std::string &tag,
+                          ScrubHeaderRefConst header,
                           MDSInternalContextBase *on_finish) {
-    enqueue_dentry(dn, recursive, children, tag, on_finish, true);
+    enqueue_dentry(dn, recursive, children, header, on_finish, true);
   }
   /** Like enqueue_dentry_top, but we wait for all pending scrubs before
    * starting this one.
    */
   void enqueue_dentry_bottom(CDentry *dn, bool recursive, bool children,
-                             const std::string &tag,
+                             ScrubHeaderRefConst header,
                              MDSInternalContextBase *on_finish) {
-    enqueue_dentry(dn, recursive, children, tag, on_finish, false);
+    enqueue_dentry(dn, recursive, children, header, on_finish, false);
   }
 
 private:
@@ -81,10 +83,10 @@ private:
    * the given scrub params, and then try and kick off more scrubbing.
    */
   void enqueue_dentry(CDentry *dn, bool recursive, bool children,
-                      const std::string &tag,
+                      ScrubHeaderRefConst header,
                       MDSInternalContextBase *on_finish, bool top);
   void _enqueue_dentry(CDentry *dn, CDir *parent, bool recursive, bool children,
-                      const std::string &tag,
+                      ScrubHeaderRefConst header,
                        MDSInternalContextBase *on_finish, bool top);
   /**
    * Kick off as many scrubs as are appropriate, based on the current