!scrub_infop->directory_scrubbing &&
!scrub_infop->need_scrub_local &&
!scrub_infop->last_scrub_dirty &&
+ !scrub_infop->pending_scrub_error &&
scrub_infop->dirty_scrub_stamps.empty()) {
delete scrub_infop;
scrub_infop = NULL;
assert(is_complete());
bool rval = check_rstats(true);
+ scrub_info();
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->pending_scrub_error = false;
scrub_infop->last_scrub_dirty = true;
- } else if (scrub_infop &&
- scrub_infop->header &&
- scrub_infop->header->repair) {
- cache->repair_dirfrag_stats(this, NULL);
+ } else {
+ scrub_infop->pending_scrub_error = true;
+ if (scrub_infop->header &&
+ scrub_infop->header->repair)
+ cache->repair_dirfrag_stats(this, NULL);
}
return rval;
}
bool directory_scrubbing; /// safety check
bool need_scrub_local;
bool last_scrub_dirty; /// is scrub info dirty or is it flushed to fnode?
+ bool pending_scrub_error;
/// these are lists of children in each stage of scrubbing
set<dentry_key_t> directories_to_scrub;
ScrubHeaderRefConst header;
scrub_info_t() :
- directory_scrubbing(false), need_scrub_local(false),
- last_scrub_dirty(false) {}
+ directory_scrubbing(false),
+ need_scrub_local(false),
+ last_scrub_dirty(false),
+ pending_scrub_error(false) {}
};
/**
* Call to start this CDir on a new scrub.
}
bool _dirfrags(int rval) {
+ int frags_errors = 0;
// basic reporting setup
results->raw_stats.checked = true;
results->raw_stats.ondisk_read_retval = rval;
assert(dir->get_version() > 0);
nest_info.add(dir->fnode.accounted_rstat);
dir_info.add(dir->fnode.accounted_fragstat);
+ if (dir->scrub_infop &&
+ dir->scrub_infop->pending_scrub_error) {
+ dir->scrub_infop->pending_scrub_error = false;
+ results->raw_stats.error_str
+ << "dirfrag(" << p->first << ") has bad stats; ";
+ frags_errors++;
+ }
}
nest_info.rsubdirs++; // it gets one to account for self
// ...and that their sum matches our inode settings
in->mdcache->repair_inode_stats(in, NULL);
goto next;
}
+ if (frags_errors > 0)
+ goto next;
+
results->raw_stats.passed = true;
next:
return true;