From: Yan, Zheng Date: Fri, 2 May 2014 08:35:08 +0000 (+0800) Subject: mds: fix-up inode's fragstat/rstat according its dirfrags X-Git-Tag: v0.81~47^2~11 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f7541067d059697fd87e45fd8f09e1f861aaa13a;p=ceph.git mds: fix-up inode's fragstat/rstat according its dirfrags Extend the code that fixup inode's fragstat/rstat to handle multiple dirfrags Signed-off-by: Yan, Zheng --- diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 325203774047..a7983ecca47d 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -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 ls; + tmpdft.get_leaves_under(frag_t(), ls); + for (list::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 ls; + tmpdft.get_leaves_under(frag_t(), ls); + for (list::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;