mds: do not complain/assert about stray inode rstat/fragstat consistency

We instantiate the stray dirfrags without reading the fragstat off of disk
because it's faster, we know the dentry is unique, and we don't care about
the stats.  It can lead to inconsistency between the dirfrag frag/rstat
and the inodes, though.  Silently clean it up when we hit it; that's
simpler than not maintaining it at all for those directories.

Signed-off-by: Sage Weil <sage.weil@dreamhost.com>
This commit is contained in:
Sage Weil 2011-08-20 20:42:30 -07:00
parent f6c07efdac
commit d3d767a2a3
2 changed files with 43 additions and 29 deletions

View File

@ -1650,15 +1650,17 @@ void CInode::finish_scatter_gather_update(int type)
if (pf->fragstat.nfiles < 0 ||
pf->fragstat.nsubdirs < 0) {
clog.error() << "bad/negative dir size on "
<< dir->dirfrag() << " " << pf->fragstat << "\n";
if (!is_stray())
clog.error() << "bad/negative dir size on "
<< dir->dirfrag() << " " << pf->fragstat << "\n";
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 (!is_stray())
assert(!"bad/negative frag size" == g_conf->mds_verify_scatter);
}
if (update) {
@ -1669,16 +1671,18 @@ void CInode::finish_scatter_gather_update(int type)
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";
if (!is_stray())
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);
if (!is_stray())
assert(!"unmatched fragstat size" == g_conf->mds_verify_scatter);
}
}
}
@ -1688,15 +1692,17 @@ void CInode::finish_scatter_gather_update(int type)
if (pi->dirstat.nfiles < 0 ||
pi->dirstat.nsubdirs < 0) {
clog.error() << "bad/negative dir size on " << ino()
<< ", inode has " << pi->dirstat << "\n";
if (!is_stray())
clog.error() << "bad/negative dir size on " << ino()
<< ", inode has " << pi->dirstat << "\n";
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);
if (!is_stray())
assert(!"bad/negative dir size" == g_conf->mds_verify_scatter);
}
}
break;
@ -1752,16 +1758,18 @@ void CInode::finish_scatter_gather_update(int type)
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";
if (!is_stray())
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 (!is_stray())
assert(!"unmatched rstat rbytes" == g_conf->mds_verify_scatter);
}
}
if (update)
@ -1771,15 +1779,17 @@ void CInode::finish_scatter_gather_update(int type)
//assert(pi->rstat.rfiles >= 0);
if (pi->rstat.rfiles < 0) {
clog.error() << "rfiles underflow " << pi->rstat.rfiles
<< " on " << *this << "\n";
if (!is_stray())
clog.error() << "rfiles underflow " << pi->rstat.rfiles
<< " on " << *this << "\n";
pi->rstat.rfiles = 0;
}
//assert(pi->rstat.rsubdirs >= 0);
if (pi->rstat.rsubdirs < 0) {
clog.error() << "rsubdirs underflow " << pi->rstat.rfiles
<< " on " << *this << "\n";
if (!is_stray())
clog.error() << "rsubdirs underflow " << pi->rstat.rfiles
<< " on " << *this << "\n";
pi->rstat.rsubdirs = 0;
}
}

View File

@ -1769,7 +1769,7 @@ void MDCache::project_rstat_frag_to_inode(nest_info_t& rstat, nest_info_t& accou
pi->rstat.add(delta);
dout(20) << " result [" << first << "," << last << "] " << pi->rstat << dendl;
if (pi->rstat.rbytes < 0)
if (pi->rstat.rbytes < 0 && !pin->is_stray())
assert(!"negative rstat rbytes" == g_conf->mds_verify_scatter);
last = first-1;
@ -2004,18 +2004,20 @@ void MDCache::predirty_journal_parents(Mutation *mut, EMetaBlob *blob,
pi->mtime = pi->ctime = pi->dirstat.mtime;
dout(20) << "predirty_journal_parents gives " << pi->dirstat << " on " << *pin << dendl;
if (pi->dirstat.size() < 0)
if (pi->dirstat.size() < 0 && !pin->is_stray())
assert(!"negative dirstat size" == g_conf->mds_verify_scatter);
if (parent->get_frag() == frag_t()) { // i.e., we are the only frag
if (pi->dirstat.size() != pf->fragstat.size()) {
mds->clog.error() << "unmatched fragstat size on single dirfrag "
<< parent->dirfrag() << ", inode has " << pi->dirstat
<< ", dirfrag has " << pf->fragstat << "\n";
if (!pin->is_stray())
mds->clog.error() << "unmatched fragstat size on single dirfrag "
<< parent->dirfrag() << ", inode has " << pi->dirstat
<< ", dirfrag has " << pf->fragstat << "\n";
// trust the dirfrag for now
pi->dirstat = pf->fragstat;
assert(!"unmatched fragstat size" == g_conf->mds_verify_scatter);
if (!pin->is_stray())
assert(!"unmatched fragstat size" == g_conf->mds_verify_scatter);
}
}
}
@ -2054,15 +2056,17 @@ void MDCache::predirty_journal_parents(Mutation *mut, EMetaBlob *blob,
pf->accounted_rstat = pf->rstat;
if (parent->get_frag() == frag_t()) { // i.e., we are the only frag
if (pi->rstat.rbytes != pf->rstat.rbytes) {
mds->clog.error() << "unmatched rstat rbytes on single dirfrag "
<< parent->dirfrag() << ", inode has " << pi->rstat
<< ", dirfrag has " << pf->rstat << "\n";
if (pi->rstat.rbytes != pf->rstat.rbytes) {
if (!pin->is_stray())
mds->clog.error() << "unmatched rstat rbytes on single dirfrag "
<< parent->dirfrag() << ", inode has " << pi->rstat
<< ", dirfrag has " << pf->rstat << "\n";
// trust the dirfrag for now
pi->rstat = pf->rstat;
assert(!"unmatched rstat rbytes" == g_conf->mds_verify_scatter);
if (!pin->is_stray())
assert(!"unmatched rstat rbytes" == g_conf->mds_verify_scatter);
}
}
}