]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: CDir: implement scrub_local() and call it in CInode::validate_disk_state()
authorGreg Farnum <gfarnum@redhat.com>
Tue, 20 Jan 2015 00:34:05 +0000 (16:34 -0800)
committerYan, Zheng <zyan@redhat.com>
Wed, 4 Nov 2015 09:17:24 +0000 (17:17 +0800)
Add another set of scrub stamps for the local scrub, which map onto the fnode
local scrub members.  Use it in CInode::validate_disk_state() instead of the
call to check_rstats, because this way we bump the scrub stats, and also
in scrub_initialize() because we know we'll have everything we need in
memory at that time, while we might not later on.

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

index 930ecb43820e3ea9cd6b262e7b3226a29a1dbd20..0cfb0faa670ddf6af63cadb9b9accdf04a57d278 100644 (file)
@@ -1264,11 +1264,16 @@ fnode_t *CDir::project_fnode()
   fnode_t *p = new fnode_t;
   *p = *get_projected_fnode();
   projected_fnode.push_back(p);
+
   if (scrub_infop && scrub_infop->last_scrub_dirty) {
+    p->localized_scrub_stamp = scrub_infop->last_local.time;
+    p->localized_scrub_version = scrub_infop->last_local.version;
     p->recursive_scrub_stamp = scrub_infop->last_recursive.time;
     p->recursive_scrub_version = scrub_infop->last_recursive.version;
     scrub_infop->last_scrub_dirty = false;
     scrub_maybe_delete_info();
+  }
+
   dout(10) << "project_fnode " << p << dendl;
   return p;
 }
@@ -2871,6 +2876,9 @@ void CDir::scrub_info_create() const
   si->last_recursive.time = si->recursive_start.time =
       fn->recursive_scrub_stamp;
 
+  si->last_local.version = fn->localized_scrub_version;
+  si->last_local.time = fn->localized_scrub_stamp;
+
   me->scrub_infop = si;
 }
 
@@ -2908,6 +2916,8 @@ void CDir::scrub_initialize()
       scrub_infop->others_to_scrub.insert(i->first);
   }
   scrub_infop->directory_scrubbing = true;
+
+  assert(scrub_local()); // TODO: handle failure
 }
 
 void CDir::scrub_finished()
@@ -3043,3 +3053,17 @@ void CDir::scrub_maybe_delete_info()
     scrub_infop = NULL;
   }
 }
+
+bool CDir::scrub_local()
+{
+  assert(is_complete());
+  bool rval = check_rstats();
+
+  if (rval) {
+    scrub_info();
+    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;
+  }
+  return rval;
+}
index 6b578892b7f7b1a706412ded4724f16dceea3576..e161d5ba9c6dd8e5ac32e7d2ec31a1643019f17a 100644 (file)
@@ -250,6 +250,8 @@ public:
 
     scrub_stamps recursive_start; // when we last started a recursive scrub
     scrub_stamps last_recursive; // when we last finished a recursive scrub
+    scrub_stamps last_local; // when we last did a local scrub
+
     bool directory_scrubbing; /// safety check
     bool last_scrub_dirty; /// is scrub info dirty or is it flushed to fnode?
 
@@ -303,6 +305,12 @@ public:
    * scrub_dentry_next's listing. It finalizes the scrub statistics.
    */
   void scrub_finished();
+  /**
+   * Tell the CDir to do a local scrub of itself.
+   * @pre The CDir is_complete().
+   * @returns true if the rstats and directory contents match, false otherwise.
+   */
+  bool scrub_local();
 private:
   /**
    * Create a scrub_info_t struct for the scrub_infop pointer.
index ae1d521205c49b053dbee3664918b1eeab6c0ac8..2e69d6f4b1d5f5296b984ccb7d0c420cb6cab9cf 100644 (file)
@@ -3812,7 +3812,7 @@ void CInode::validate_disk_state(CInode::validated_data *results,
           results->raw_rstats.error_str << "dirfrag is INCOMPLETE despite fetching; probably too large compared to MDS cache size?\n";
           return true;
         }
-        assert(p->second->check_rstats());
+        assert(p->second->scrub_local());
         sub_info.add(p->second->fnode.accounted_rstat);
       }
       // ...and that their sum matches our inode settings