]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: fix-up inode's fragstat/rstat according its dirfrags
authorYan, Zheng <zheng.z.yan@intel.com>
Fri, 2 May 2014 08:35:08 +0000 (16:35 +0800)
committerYan, Zheng <zheng.z.yan@intel.com>
Tue, 6 May 2014 23:10:16 +0000 (07:10 +0800)
Extend the code that fixup inode's fragstat/rstat to handle multiple
dirfrags

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
src/mds/CInode.cc

index 3252037740470dfd07a9254f0d1a7c8f25256865..a7983ecca47da62196741768e4b5fd2aab27edbc 100644 (file)
@@ -1758,6 +1758,9 @@ void CInode::finish_scatter_gather_update(int type)
   switch (type) {
   case CEPH_LOCK_IFILE:
     {
+      fragtree_t tmpdft = dirfragtree;
+      struct frag_info_t dirstat;
+
       // adjust summation
       assert(is_auth());
       inode_t *pi = get_projected_inode();
@@ -1790,13 +1793,12 @@ void CInode::finish_scatter_gather_update(int type)
            pf->fragstat.nsubdirs < 0) {
          clog.error() << "bad/negative dir size on "
              << dir->dirfrag() << " " << pf->fragstat << "\n";
+         assert(!"bad/negative fragstat" == g_conf->mds_verify_scatter);
          
          if (pf->fragstat.nfiles < 0)
            pf->fragstat.nfiles = 0;
          if (pf->fragstat.nsubdirs < 0)
            pf->fragstat.nsubdirs = 0;
-
-         assert(!"bad/negative frag size" == g_conf->mds_verify_scatter);
        }
 
        if (update) {
@@ -1805,42 +1807,54 @@ void CInode::finish_scatter_gather_update(int type)
          dout(10) << fg << " updated accounted_fragstat " << pf->fragstat << " on " << *dir << dendl;
        }
 
-       if (fg == frag_t()) { // i.e., we are the only frag
-         if (pi->dirstat.size() != pf->fragstat.size()) {
-           clog.error() << "unmatched fragstat size on single "
-              << "dirfrag " << dir->dirfrag() << ", inode has " 
-              << pi->dirstat << ", dirfrag has " << pf->fragstat << "\n";
-           
-           // trust the dirfrag for now
-           version_t v = pi->dirstat.version;
-           pi->dirstat = pf->fragstat;
-           pi->dirstat.version = v;
-
-           assert(!"unmatched fragstat size" == g_conf->mds_verify_scatter);
-         }
-       }
+       tmpdft.force_to_leaf(g_ceph_context, fg);
+       dirstat.add(pf->fragstat);
       }
       if (touched_mtime)
        pi->mtime = pi->ctime = pi->dirstat.mtime;
       dout(20) << " final dirstat " << pi->dirstat << dendl;
 
+      if (dirstat.nfiles != pi->dirstat.nfiles ||
+         dirstat.nsubdirs != pi->dirstat.nsubdirs) {
+       bool all = true;
+       list<frag_t> ls;
+       tmpdft.get_leaves_under(frag_t(), ls);
+       for (list<frag_t>::iterator p = ls.begin(); p != ls.end(); ++p)
+         if (!dirfrags.count(*p)) {
+           all = false;
+           break;
+         }
+       if (all) {
+         clog.error() << "unmatched fragstat on " << ino() << ", inode has "
+                      << pi->dirstat << ", dirfrags have " << dirstat << "\n";
+         assert(!"unmatched fragstat" == g_conf->mds_verify_scatter);
+         // trust the dirfrags for now
+         version_t v = pi->dirstat.version;
+         pi->dirstat = dirstat;
+         pi->dirstat.version = v;
+       }
+      }
+
       if (pi->dirstat.nfiles < 0 ||
          pi->dirstat.nsubdirs < 0) {
-       clog.error() << "bad/negative dir size on " << ino()
+       clog.error() << "bad/negative fragstat on " << ino()
            << ", inode has " << pi->dirstat << "\n";
+       assert(!"bad/negative fragstat" == g_conf->mds_verify_scatter);
 
        if (pi->dirstat.nfiles < 0)
          pi->dirstat.nfiles = 0;
        if (pi->dirstat.nsubdirs < 0)
          pi->dirstat.nsubdirs = 0;
-
-       assert(!"bad/negative dir size" == g_conf->mds_verify_scatter);
       }
     }
     break;
 
   case CEPH_LOCK_INEST:
     {
+      fragtree_t tmpdft = dirfragtree;
+      nest_info_t rstat;
+      rstat.rsubdirs = 1;
+
       // adjust summation
       assert(is_auth());
       inode_t *pi = get_projected_inode();
@@ -1885,40 +1899,51 @@ void CInode::finish_scatter_gather_update(int type)
          pf->accounted_rstat = pf->rstat;
          dir->dirty_old_rstat.clear();
          pf->rstat.version = pf->accounted_rstat.version = pi->rstat.version;
+         dir->check_rstats();
          dout(10) << fg << " updated accounted_rstat " << pf->rstat << " on " << *dir << dendl;
        }
 
-       if (fg == frag_t()) { // i.e., we are the only frag
-         if (pi->rstat.rbytes != pf->rstat.rbytes) { 
-           clog.error() << "unmatched rstat rbytes on single dirfrag "
-               << dir->dirfrag() << ", inode has " << pi->rstat
-               << ", dirfrag has " << pf->rstat << "\n";
-           
-           // trust the dirfrag for now
-           version_t v = pi->rstat.version;
-           pi->rstat = pf->rstat;
-           pi->rstat.version = v;
-           
-           assert(!"unmatched rstat rbytes" == g_conf->mds_verify_scatter);
-         }
-       }
-       if (update)
-         dir->check_rstats();
+       tmpdft.force_to_leaf(g_ceph_context, fg);
+       rstat.add(pf->rstat);
       }
       dout(20) << " final rstat " << pi->rstat << dendl;
 
-      //assert(pi->rstat.rfiles >= 0);
-      if (pi->rstat.rfiles < 0) {
-       clog.error() << "rfiles underflow " << pi->rstat.rfiles
-                    << " on " << *this << "\n";
-       pi->rstat.rfiles = 0;
+      if (rstat.rfiles != pi->rstat.rfiles ||
+         rstat.rsubdirs != pi->rstat.rsubdirs ||
+         rstat.rbytes != pi->rstat.rbytes) {
+       bool all = true;
+       list<frag_t> ls;
+       tmpdft.get_leaves_under(frag_t(), ls);
+       for (list<frag_t>::iterator p = ls.begin(); p != ls.end(); ++p)
+         if (!dirfrags.count(*p)) {
+           all = false;
+           break;
+         }
+       if (all) {
+         clog.error() << "unmatched rstat on " << ino() << ", inode has "
+                      << pi->rstat << ", dirfrags have " << rstat << "\n";
+         assert(!"unmatched rstat" == g_conf->mds_verify_scatter);
+         // trust the dirfrag for now
+         version_t v = pi->rstat.version;
+         pi->rstat = rstat;
+         pi->rstat.version = v;
+       }
       }
 
-      //assert(pi->rstat.rsubdirs >= 0);
-      if (pi->rstat.rsubdirs < 0) {
-       clog.error() << "rsubdirs underflow " << pi->rstat.rsubdirs
-                    << " on " << *this << "\n";
-       pi->rstat.rsubdirs = 0;
+      if (pi->rstat.rsubdirs < 0 ||
+         pi->rstat.rfiles < 0 ||
+         pi->rstat.rbytes < 0) {
+       clog.error() << "bad/negative rstat on " << ino()
+                    << ", inode has " << pi->rstat << "\n";
+
+       if (pi->rstat.rsubdirs < 0)
+         pi->rstat.rsubdirs = 0;
+       if (pi->rstat.rfiles < 0)
+         pi->rstat.rfiles = 0;
+       if (pi->rstat.rbytes < 0)
+         pi->rstat.rbytes = 0;
+
+       assert(!"bad/negative rstat" == g_conf->mds_verify_scatter);
       }
     }
     break;