]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: use scrubstack code to scrub single dentry
authorYan, Zheng <zyan@redhat.com>
Fri, 11 Dec 2015 10:11:52 +0000 (18:11 +0800)
committerYan, Zheng <zyan@redhat.com>
Mon, 7 Mar 2016 07:59:13 +0000 (15:59 +0800)
Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/mds/MDCache.cc
src/mds/MDCache.h
src/mds/MDSRank.cc
src/mds/ScrubHeader.h
src/mds/ScrubStack.cc
src/mds/ScrubStack.h

index 712687f16ebd7fddf37f14be7bd6d495df6f0d40..e1fa92d0d848a143dc6d6d1ee556a7b573a16218 100644 (file)
@@ -11714,21 +11714,6 @@ void MDCache::scrub_dentry(const string& path, Formatter *f, Context *fin)
   scrub_dentry_work(mdr);
 }
 
-/**
- * The private data for an OP_ENQUEUE_SCRUB MDRequest
- */
-class EnqueueScrubParams
-{
-  public:
-  const bool recursive;
-  const bool children;
-  const std::string tag;
-  EnqueueScrubParams(bool r, bool c, const std::string &tag_)
-    : recursive(r), children(c), tag(tag_)
-  {}
-};
-
-
 void MDCache::scrub_dentry_work(MDRequestRef& mdr)
 {
   set<SimpleLock*> rdlocks, wrlocks, xlocks;
@@ -11750,45 +11735,50 @@ void MDCache::scrub_dentry_work(MDRequestRef& mdr)
   return;
 }
 
-
-class C_ScrubEnqueued : public Context
+class C_MDS_EnqueueScrub : public Context
 {
-public:
-  MDRequestRef mdr;
-  Context *on_finish;
   Formatter *formatter;
-  C_ScrubEnqueued(MDRequestRef& mdr,
-                  Context *fin, Formatter *f) :
-    mdr(mdr), on_finish(fin), formatter(f) {}
+  Context *on_finish;
+public:
+  ScrubHeaderRef header;
+  C_MDS_EnqueueScrub(Formatter *f, Context *fin) :
+    formatter(f), on_finish(fin), header(new ScrubHeader()) {}
+
+  Context *take_finisher() {
+    Context *fin = on_finish;
+    on_finish = NULL;
+    return fin;
+  }
 
   void finish(int r) {
-#if 0
-    if (r >= 0) { // we got into the scrubbing dump it
-      results.dump(formatter);
-    } else { // we failed the lookup or something; dump ourselves
+    if (r < 0) { // we failed the lookup or something; dump ourselves
       formatter->open_object_section("results");
       formatter->dump_int("return_code", r);
       formatter->close_section(); // results
     }
-#endif
-    on_finish->complete(r);
+    if (on_finish)
+      on_finish->complete(r);
   }
 };
 
 void MDCache::enqueue_scrub(
     const string& path,
     const std::string &tag,
+    bool recursive,
     Formatter *f, Context *fin)
 {
-  dout(10) << "scrub_dentry " << path << dendl;
+  dout(10) << __func__ << path << dendl;
   MDRequestRef mdr = request_start_internal(CEPH_MDS_OP_ENQUEUE_SCRUB);
   filepath fp(path.c_str());
   mdr->set_filepath(fp);
 
-  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, tag);
+  C_MDS_EnqueueScrub *cs = new C_MDS_EnqueueScrub(f, fin);
+  ScrubHeaderRef &header = cs->header;
+  header->tag = tag;
+  header->recursive = recursive;
+  header->formatter = f;
+
+  mdr->internal_op_finish = cs;
   enqueue_scrub_work(mdr);
 }
 
@@ -11807,15 +11797,11 @@ void MDCache::enqueue_scrub_work(MDRequestRef& mdr)
     return;
 
   CDentry *dn = in->get_parent_dn();
-
   // We got to this inode by path, so it must have a parent
   assert(dn != NULL);
 
-  // Not setting a completion context here because we don't
-  // want to block asok caller on long running scrub
-  EnqueueScrubParams *args = static_cast<EnqueueScrubParams*>(
-      mdr->internal_op_private);
-  assert(args != NULL);
+  C_MDS_EnqueueScrub *cs = static_cast<C_MDS_EnqueueScrub*>(mdr->internal_op_finish);
+  ScrubHeaderRef &header = cs->header;
 
   // Cannot scrub same dentry twice at same time
   if (dn->scrub_info()->dentry_scrubbing) {
@@ -11823,16 +11809,16 @@ void MDCache::enqueue_scrub_work(MDRequestRef& mdr)
     return;
   }
 
-  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;
+  // only set completion context for non-recursive scrub, because we don't 
+  // want to block asok caller on long running scrub
+  Context *fin = NULL;
+  if (!header->recursive)
+    fin = cs->take_finisher();
+
+  mds->scrubstack->enqueue_dentry_bottom(dn, header->recursive, false, header, fin);
 
-  // Successfully enqueued
   mds->server->respond_to_request(mdr, 0);
   return;
 }
index 5b29cd6df5a205a4abca1ef2af1465cc6aeb428c..2f25dc948b5aeef5129f4024a6c189de8552ea3b 100644 (file)
@@ -1154,7 +1154,7 @@ public:
    * Create and start an OP_ENQUEUE_SCRUB
    */
   void enqueue_scrub(const string& path, const std::string &tag,
-                     Formatter *f, Context *fin);
+                     bool recursive, Formatter *f, Context *fin);
   void repair_inode_stats(CInode *diri, Context *fin);
   void repair_dirfrag_stats(CDir *dir, Context *fin);
 };
index 44d6e3d964ee9d066fc81876839430a2880298b0..42315fffeced5db275436c75859cdc7d0f7635c0 100644 (file)
@@ -1879,7 +1879,7 @@ void MDSRank::command_scrub_path(Formatter *f, const string& path)
   C_SaferCond scond;
   {
     Mutex::Locker l(mds_lock);
-    mdcache->scrub_dentry(path, f, &scond);
+    mdcache->enqueue_scrub(path, "", false, f, &scond);
   }
   scond.wait();
   // scrub_dentry() finishers will dump the data for us; we're done!
@@ -1891,7 +1891,7 @@ void MDSRank::command_tag_path(Formatter *f,
   C_SaferCond scond;
   {
     Mutex::Locker l(mds_lock);
-    mdcache->enqueue_scrub(path, tag, f, &scond);
+    mdcache->enqueue_scrub(path, tag, true, f, &scond);
   }
   scond.wait();
 }
index 288f3a38a19c6c2c8b18deb5dfa43a872bce5c3d..46783ed680f93ec85ffd75572ca30ba8e9bb7072 100644 (file)
@@ -13,8 +13,11 @@ class CDentry;
  */
 class ScrubHeader {
 public:
-  std::string tag;
   CDentry *origin;
+  std::string tag;
+
+  bool recursive;
+  Formatter *formatter;
 };
 typedef ceph::shared_ptr<ScrubHeader> ScrubHeaderRef;
 typedef ceph::shared_ptr<const ScrubHeader> ScrubHeaderRefConst;
index f624f33a7fa847682827ae8556d228f3480d3a7a..fdade7c4b4e9352dd17e5f2998a24d7bfdb2756f 100644 (file)
@@ -59,7 +59,7 @@ void ScrubStack::pop_dentry(CDentry *dn)
 
 void ScrubStack::_enqueue_dentry(CDentry *dn, CDir *parent, bool recursive,
     bool children, const ScrubHeaderRefConst& header,
-    MDSInternalContextBase *on_finish, bool top)
+    Context *on_finish, bool top)
 {
   dout(10) << __func__ << " with {" << *dn << "}"
            << ", recursive=" << recursive << ", children=" << children
@@ -74,7 +74,7 @@ void ScrubStack::_enqueue_dentry(CDentry *dn, CDir *parent, bool recursive,
 
 void ScrubStack::enqueue_dentry(CDentry *dn, bool recursive, bool children,
                                 const ScrubHeaderRefConst& header,
-                                 MDSInternalContextBase *on_finish, bool top)
+                                Context *on_finish, bool top)
 {
   _enqueue_dentry(dn, NULL, recursive, children, header, on_finish, top);
   kick_off_scrubs();
@@ -425,6 +425,7 @@ void ScrubStack::_validate_inode_done(CDentry *dn, int r,
   assert(dn->scrub_info_p != NULL);
   dn->scrub_info_p->inode_validated = true;
 #endif
+  const ScrubHeaderRefConst header = dn->scrub_info()->header;
 
   Context *c = NULL;
   CInode *in = dn->get_projected_inode();
@@ -436,6 +437,16 @@ void ScrubStack::_validate_inode_done(CDentry *dn, int r,
     // just the dentry.
     dn->scrub_finished(&c);
   }
+
+  if (!header->recursive && dn == header->origin) {
+    if (r >= 0) { // we got into the scrubbing dump it
+      result.dump(header->formatter);
+    } else { // we failed the lookup or something; dump ourselves
+      header->formatter->open_object_section("results");
+      header->formatter->dump_int("return_code", r);
+      header->formatter->close_section(); // results
+    }
+  }
   if (c) {
     finisher->queue(new MDSIOContextWrapper(mdcache->mds, c), 0);
   }
index 96e1383d1818098b42c82ef168bfb2b75e068377..87f3ca242e6ff4dedd34b4129e4611fdab701c5a 100644 (file)
@@ -80,7 +80,7 @@ public:
    */
   void enqueue_dentry_top(CDentry *dn, bool recursive, bool children,
                           const ScrubHeaderRefConst& header,
-                          MDSInternalContextBase *on_finish) {
+                          Context *on_finish) {
     enqueue_dentry(dn, recursive, children, header, on_finish, true);
   }
   /** Like enqueue_dentry_top, but we wait for all pending scrubs before
@@ -88,7 +88,7 @@ public:
    */
   void enqueue_dentry_bottom(CDentry *dn, bool recursive, bool children,
                              const ScrubHeaderRefConst& header,
-                             MDSInternalContextBase *on_finish) {
+                             Context *on_finish) {
     enqueue_dentry(dn, recursive, children, header, on_finish, false);
   }
 
@@ -99,10 +99,10 @@ private:
    */
   void enqueue_dentry(CDentry *dn, bool recursive, bool children,
                       const ScrubHeaderRefConst& header,
-                      MDSInternalContextBase *on_finish, bool top);
+                      Context *on_finish, bool top);
   void _enqueue_dentry(CDentry *dn, CDir *parent, bool recursive, bool children,
                       const ScrubHeaderRefConst& header,
-                       MDSInternalContextBase *on_finish, bool top);
+                      Context *on_finish, bool top);
   /**
    * Kick off as many scrubs as are appropriate, based on the current
    * state of the stack.