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();
{
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;
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
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.
shadow_in->fetch(get_internal_callback(INODE));
return false;
} else {
- return fetch_dirfrag_rstats();
+ return check_dirfrag_rstats();
}
}
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));
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;