]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: CDentry: create scrub_info_t and surrounding infrastructure
authorGreg Farnum <gfarnum@redhat.com>
Tue, 20 Jan 2015 19:27:47 +0000 (11:27 -0800)
committerYan, Zheng <zyan@redhat.com>
Wed, 4 Nov 2015 09:17:24 +0000 (17:17 +0800)
The CDentry is going to be the point of entry for scrubbing code, and
is how we maintain our cache size. Therefore, it gets a scrub_parent pointer
and a new PIN_SCRUBQUEUE in addition to the basic scrub_info_t struct and
scrub_initialize() and scrub_finish() functions.

Signed-off-by: Greg Farnum <gfarnum@redhat.com>
src/mds/CDentry.cc
src/mds/CDentry.h

index e56c66af6319633a38c897b697614376867e4682..d40b5a02574b8d7f6dbfb25e6ead908dddb9257a 100644 (file)
@@ -622,3 +622,47 @@ std::string CDentry::linkage_t::get_remote_d_type_string() const
   }
 }
 
+void CDentry::scrub_initialize(CDir *parent, bool recurse, bool children,
+                               Context *f)
+{
+  if (!scrub_infop)
+    scrub_info_create();
+  else
+    assert(!scrub_infop->dentry_scrubbing);
+
+  scrub_infop->scrub_parent = parent;
+  scrub_infop->scrub_recursive = recurse;
+  scrub_infop->scrub_children = children;
+  scrub_infop->dentry_scrubbing = true;
+  scrub_infop->on_finish = f;
+
+  auth_pin(this);
+}
+
+void CDentry::scrub_finished(Context **c)
+{
+  dout(10) << __func__ << dendl;
+  assert(scrub_info()->dentry_scrubbing);
+
+  if (scrub_infop->scrub_parent) {
+    scrub_infop->scrub_parent->scrub_dentry_finished(this);
+  }
+
+  *c = scrub_infop->on_finish;
+
+  delete scrub_infop;
+  scrub_infop = NULL;
+
+  auth_unpin(this);
+}
+
+void CDentry::scrub_info_create() const
+{
+  assert(!scrub_infop);
+
+  // break out of const-land to set up implicit initial state
+  CDentry *me = const_cast<CDentry*>(this);
+
+  // we don't need to change or set up any default parameters; assign directly
+  me->scrub_infop = new scrub_info_t();
+}
index 40a4723601cd05bf00707a2a6852e7eb143a43e1..424b8fdd60427cb282315a3a99a3451bd9873155 100644 (file)
@@ -80,11 +80,14 @@ public:
   static const int PIN_INODEPIN =     1;  // linked inode is pinned
   static const int PIN_FRAGMENTING = -2;  // containing dir is refragmenting
   static const int PIN_PURGING =      3;
+  static const int PIN_SCRUBQUEUE =   4; // TODO: negative value?
+
   const char *pin_name(int p) const {
     switch (p) {
     case PIN_INODEPIN: return "inodepin";
     case PIN_FRAGMENTING: return "fragmenting";
     case PIN_PURGING: return "purging";
+    case PIN_SCRUBQUEUE: return "scrub_enqueued";
     default: return generic_pin_name(p);
     }
   }
@@ -137,6 +140,19 @@ public:
     void link_remote(CInode *in);
   };
   
+  class scrub_info_t {
+  public:
+    CDir *scrub_parent; /// This either matches get_parent_dir() or NULL
+    bool scrub_recursive; /// true if we are scrubbing everything under this
+    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
+    scrub_info_t() :
+      scrub_parent(NULL), scrub_recursive(false),
+      scrub_children(false), dentry_scrubbing(false), on_finish(NULL)
+    {}
+  };
+
 protected:
   CDir *dir;     // containing dirfrag
   linkage_t linkage;
@@ -144,11 +160,27 @@ protected:
   
   version_t version;  // dir version when last touched.
   version_t projected_version;  // what it will be when i unlock/commit.
+  scrub_info_t* scrub_infop;
 
 public:
   elist<CDentry*>::item item_dirty;
   elist<CDentry*>::item item_stray;
 
+  const scrub_info_t *scrub_info() const {
+    if(!scrub_infop)
+      scrub_info_create();
+    return scrub_infop;
+  }
+  void scrub_initialize(CDir *parent, bool recurse, bool children,
+                        Context *f);
+  void scrub_finished(Context **c);
+
+private:
+  /**
+   * Create a scrub_info_t struct for the scrub_infop pointer.
+   */
+  void scrub_info_create() const;
+
 protected:
   friend class Migrator;
   friend class Locker;
@@ -174,6 +206,7 @@ public:
     first(f), last(l),
     dir(0),
     version(0), projected_version(0),
+    scrub_infop(NULL),
     item_dirty(this),
     lock(this, &lock_type),
     versionlock(this, &versionlock_type) {
@@ -186,6 +219,7 @@ public:
     first(f), last(l),
     dir(0),
     version(0), projected_version(0),
+    scrub_infop(NULL),
     item_dirty(this),
     lock(this, &lock_type),
     versionlock(this, &versionlock_type) {
@@ -195,6 +229,7 @@ public:
     linkage.remote_d_type = dt;
   }
   ~CDentry() {
+    assert(!scrub_infop);
     g_num_dn--;
     g_num_dns++;
   }