]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: check dirfrag rstat when dirfrag is fetched
authorYan, Zheng <zyan@redhat.com>
Fri, 20 Nov 2015 08:36:55 +0000 (16:36 +0800)
committerYan, Zheng <zyan@redhat.com>
Mon, 7 Mar 2016 07:59:12 +0000 (15:59 +0800)
This avoids the problem that dirfrag becomes imcomplete before
ValidationContinuation::_dirfrags() get called;

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

index e0a06ef4965656d8640f7355f37fdd73d6f42d77..5721cbaa3dbc362cc25edeb4fecb25c555c5663a 100644 (file)
@@ -1857,6 +1857,11 @@ void CDir::_omap_fetched(bufferlist& hdrbl, map<string, bufferlist>& omap,
   mark_complete();
   state_clear(STATE_FETCHING);
 
+  if (scrub_infop && scrub_infop->need_scrub_local) {
+    scrub_infop->need_scrub_local = false;
+    scrub_local();
+  }
+
   // open & force frags
   while (!undef_inodes.empty()) {
     CInode *in = undef_inodes.front();
@@ -3059,6 +3064,7 @@ void CDir::scrub_maybe_delete_info()
 {
   if (scrub_infop &&
       !scrub_infop->directory_scrubbing &&
+      !scrub_infop->need_scrub_local &&
       !scrub_infop->last_scrub_dirty &&
       scrub_infop->dirty_scrub_stamps.empty()) {
     delete scrub_infop;
index 44034b8d475ffe3cbbe7f6c833c95deba45a9263..857eb385168f2d6d0a89dc63e679d99c433ad6ce 100644 (file)
@@ -253,6 +253,7 @@ public:
     scrub_stamps last_local; // when we last did a local scrub
 
     bool directory_scrubbing; /// safety check
+    bool need_scrub_local;
     bool last_scrub_dirty; /// is scrub info dirty or is it flushed to fnode?
 
     /// these are lists of children in each stage of scrubbing
@@ -263,7 +264,9 @@ public:
     set<dentry_key_t> others_scrubbing;
     set<dentry_key_t> others_scrubbed;
 
-    scrub_info_t() : directory_scrubbing(false), last_scrub_dirty(false) {}
+    scrub_info_t() :
+      directory_scrubbing(false), need_scrub_local(false),
+      last_scrub_dirty(false) {}
   };
   /**
    * Call to start this CDir on a new scrub.
index e79d5c381e76cca786f7c5c5825ca09414bdaa9b..fd8cf8485ed994a73169a9aefbc666e7b1006b6e 100644 (file)
@@ -3864,7 +3864,7 @@ void CInode::validate_disk_state(CInode::validated_data *results,
         shadow_in->fetch(get_internal_callback(INODE));
         return false;
       } else {
-        return fetch_dirfrag_rstats();
+        return check_dirfrag_rstats();
       }
     }
 
@@ -3891,19 +3891,24 @@ void CInode::validate_disk_state(CInode::validated_data *results,
           return true;
         }
       }
-      return fetch_dirfrag_rstats();
+      return check_dirfrag_rstats();
     }
 
-    bool fetch_dirfrag_rstats() {
+    bool check_dirfrag_rstats() {
       MDSGatherBuilder gather(g_ceph_context);
       std::list<frag_t> frags;
       in->dirfragtree.get_leaves(frags);
       for (list<frag_t>::iterator p = frags.begin();
           p != frags.end();
           ++p) {
-        CDir *dirfrag = in->get_or_open_dirfrag(in->mdcache, *p);
-        if (!dirfrag->is_complete())
-          dirfrag->fetch(gather.new_sub(), false);
+        CDir *dir = in->get_or_open_dirfrag(in->mdcache, *p);
+        if (dir->is_complete()) {
+         dir->scrub_local();
+       } else {
+         dir->scrub_info();
+         dir->scrub_infop->need_scrub_local = true;
+         dir->fetch(gather.new_sub(), false);
+       }
       }
       if (gather.has_subs()) {
         gather.set_finisher(get_internal_callback(DIRFRAGS));
@@ -3929,13 +3934,9 @@ void CInode::validate_disk_state(CInode::validated_data *results,
       for (compact_map<frag_t,CDir*>::iterator p = in->dirfrags.begin();
           p != in->dirfrags.end();
           ++p) {
-        if (!p->second->is_complete()) {
-          results->raw_rstats.error_str << "dirfrag is INCOMPLETE despite fetching; probably too large compared to MDS cache size?\n";
-          return true;
-        }
-        // FIXME!!! Don't assert out on damage!
-        assert(p->second->scrub_local());
-        sub_info.add(p->second->fnode.accounted_rstat);
+       CDir *dir = p->second;
+       assert(dir->get_version() > 0);
+       sub_info.add(dir->fnode.accounted_rstat);
       }
       // ...and that their sum matches our inode settings
       results->raw_rstats.memory_value = in->inode.rstat;