me->scrub_infop = si;
}
-void CDir::scrub_initialize()
+void CDir::scrub_initialize(const ScrubHeaderRefConst& header)
{
dout(20) << __func__ << dendl;
assert(is_complete());
}
}
scrub_infop->directory_scrubbing = true;
+ scrub_infop->header = header;
}
void CDir::scrub_finished()
// okay, we got a dentry
dns.erase(dnkey);
- if (dn->get_projected_version() < scrub_infop->last_recursive.version) {
+ if (dn->get_projected_version() < scrub_infop->last_recursive.version &&
+ !(scrub_infop->header && scrub_infop->header->force)) {
dout(15) << " skip dentry " << dnkey.name
<< ", no change since last scrub" << dendl;
continue;
scrub_infop->last_local.time = ceph_clock_now(g_ceph_context);
scrub_infop->last_local.version = get_projected_version();
scrub_infop->last_scrub_dirty = true;
- } else if (inode->scrub_infop &&
- inode->scrub_infop->header &&
- inode->scrub_infop->header->repair) {
+ } else if (scrub_infop &&
+ scrub_infop->header &&
+ scrub_infop->header->repair) {
cache->repair_dirfrag_stats(this, NULL);
}
return rval;
set<dentry_key_t> others_scrubbing;
set<dentry_key_t> others_scrubbed;
+ ScrubHeaderRefConst header;
+
scrub_info_t() :
directory_scrubbing(false), need_scrub_local(false),
last_scrub_dirty(false) {}
* @pre The CDir is marked complete.
* @post It has set up its internal scrubbing state.
*/
- void scrub_initialize();
+ void scrub_initialize(const ScrubHeaderRefConst& header);
/**
* Get the next dentry to scrub. Gives you a CDentry* and its meaning. This
* function will give you all directory-representing dentries before any
for (std::list<frag_t>::iterator i = frags.begin();
i != frags.end();
++i) {
- scrub_infop->dirfrag_stamps[*i];
+ if (header->force)
+ scrub_infop->dirfrag_stamps[*i].reset();
+ else
+ scrub_infop->dirfrag_stamps[*i];
}
}
/// time we started our most recent finished scrub
utime_t last_scrub_stamp;
scrub_stamp_info_t() : scrub_start_version(0), last_scrub_version(0) {}
+ void reset() {
+ scrub_start_version = 0;
+ scrub_start_stamp = utime_t();
+ }
};
class scrub_info_t : public scrub_stamp_info_t {
void MDCache::enqueue_scrub(
const string& path,
const std::string &tag,
- bool recursive, bool repair,
+ bool force, bool recursive, bool repair,
Formatter *f, Context *fin)
{
dout(10) << __func__ << path << dendl;
C_MDS_EnqueueScrub *cs = new C_MDS_EnqueueScrub(f, fin);
ScrubHeaderRef &header = cs->header;
header->tag = tag;
+ header->force = force;
header->recursive = recursive;
header->repair = repair;
header->formatter = f;
* Create and start an OP_ENQUEUE_SCRUB
*/
void enqueue_scrub(const string& path, const std::string &tag,
- bool recursive, bool repair, Formatter *f, Context *fin);
+ bool force, bool recursive, bool repair,
+ Formatter *f, Context *fin);
void repair_inode_stats(CInode *diri, Context *fin);
void repair_dirfrag_stats(CDir *dir, Context *fin);
};
assert(r == 0);
r = admin_socket->register_command("scrub_path",
"scrub_path name=path,type=CephString "
- "name=scrubops,type=CephChoices,strings=recursive|repair,n=N,req=false",
+ "name=scrubops,type=CephChoices,"
+ "strings=force|recursive|repair,n=N,req=false",
asok_hook,
"scrub an inode and output results");
assert(r == 0);
void MDSRank::command_scrub_path(Formatter *f, const string& path, vector<string>& scrubop_vec)
{
+ bool force = false;
bool recursive = false;
bool repair = false;
for (vector<string>::iterator i = scrubop_vec.begin() ; i != scrubop_vec.end(); ++i) {
- if (*i == "recursive")
+ if (*i == "force")
+ force = true;
+ else if (*i == "recursive")
recursive = true;
else if (*i == "repair")
repair = true;
C_SaferCond scond;
{
Mutex::Locker l(mds_lock);
- mdcache->enqueue_scrub(path, "", recursive, repair, f, &scond);
+ mdcache->enqueue_scrub(path, "", force, recursive, repair, f, &scond);
}
scond.wait();
// scrub_dentry() finishers will dump the data for us; we're done!
C_SaferCond scond;
{
Mutex::Locker l(mds_lock);
- mdcache->enqueue_scrub(path, tag, true, false, f, &scond);
+ mdcache->enqueue_scrub(path, tag, true, true, false, f, &scond);
}
scond.wait();
}
CInode *origin;
std::string tag;
+ bool force;
bool recursive;
bool repair;
Formatter *formatter;
return;
}
- dir->scrub_initialize();
+ dir->scrub_initialize(header);
}
int r = 0;