case CEPH_MDS_OP_GETFILELOCK: return "getfilelock";
case CEPH_MDS_OP_FRAGMENTDIR: return "fragmentdir";
case CEPH_MDS_OP_EXPORTDIR: return "exportdir";
- case CEPH_MDS_OP_VALIDATE: return "validate_path";
case CEPH_MDS_OP_FLUSH: return "flush_path";
+ case CEPH_MDS_OP_ENQUEUE_SCRUB: return "enqueue_scrub";
case CEPH_MDS_OP_REPAIR_FRAGSTATS: return "repair_fragstats";
case CEPH_MDS_OP_REPAIR_INODESTATS: return "repair_inodestats";
}
// internal op
CEPH_MDS_OP_FRAGMENTDIR= 0x01500,
CEPH_MDS_OP_EXPORTDIR = 0x01501,
- CEPH_MDS_OP_VALIDATE = 0x01502,
- CEPH_MDS_OP_FLUSH = 0x01503,
- CEPH_MDS_OP_ENQUEUE_SCRUB = 0x01504,
- CEPH_MDS_OP_REPAIR_FRAGSTATS = 0x01505,
- CEPH_MDS_OP_REPAIR_INODESTATS = 0x01506
+ CEPH_MDS_OP_FLUSH = 0x01502,
+ CEPH_MDS_OP_ENQUEUE_SCRUB = 0x01503,
+ CEPH_MDS_OP_REPAIR_FRAGSTATS = 0x01504,
+ CEPH_MDS_OP_REPAIR_INODESTATS = 0x01505
};
extern const char *ceph_mds_op_name(int op);
}
void CInode::validate_disk_state(CInode::validated_data *results,
- MDRequestRef &mdr, MDSInternalContext *fin)
+ MDSInternalContext *fin)
{
class ValidationContinuation : public MDSContinuation {
public:
- MDRequestRef mdr;
MDSInternalContext *fin;
CInode *in;
CInode::validated_data *results;
DIRFRAGS
};
- /**
- * May set either mdr or fin, depending on whether caller is doing
- * validation in a single MDRequest (i.e. asok) or caller is doing
- * their own thing (i.e. ScrubStack)
- */
ValidationContinuation(CInode *i,
CInode::validated_data *data_r,
- MDRequestRef &_mdr,
MDSInternalContext *fin_) :
MDSContinuation(i->mdcache->mds->server),
- mdr(_mdr),
fin(fin_),
in(i),
results(data_r),
results->backtrace.passed &&
results->inode.passed)
results->passed_validation = true;
- if (mdr) {
- server->respond_to_request(mdr, get_rval());
- } else if (fin) {
+ if (fin) {
fin->complete(get_rval());
}
delete this;
dout(10) << "scrub starting validate_disk_state on " << *this << dendl;
ValidationContinuation *vc = new ValidationContinuation(this,
results,
- mdr,
fin);
vc->begin();
}
* @param fin Context to call back on completion (or NULL)
*/
void validate_disk_state(validated_data *results,
- MDRequestRef& mdr,
MDSInternalContext *fin);
static void dump_validation_results(const validated_data& results,
Formatter *f);
case CEPH_MDS_OP_EXPORTDIR:
migrator->dispatch_export_dir(mdr);
break;
- case CEPH_MDS_OP_VALIDATE:
- scrub_dentry_work(mdr);
- break;
case CEPH_MDS_OP_ENQUEUE_SCRUB:
enqueue_scrub_work(mdr);
break;
cache->dispatch_request(mdr);
}
-class C_scrub_dentry_finish : public Context {
-public:
- CInode::validated_data results;
- MDRequestRef mdr;
- Context *on_finish;
- Formatter *formatter;
- C_scrub_dentry_finish(MDRequestRef& mdr,
- Context *fin, Formatter *f) :
- mdr(mdr), on_finish(fin), formatter(f) {}
-
- void finish(int r) {
- if (r >= 0) { // we got into the scrubbing dump it
- results.dump(formatter);
- } else { // we failed the lookup or something; dump ourselves
- formatter->open_object_section("results");
- formatter->dump_int("return_code", r);
- formatter->close_section(); // results
- }
- on_finish->complete(r);
- }
-};
-
-void MDCache::scrub_dentry(const string& path, Formatter *f, Context *fin)
-{
- dout(10) << "scrub_dentry " << path << dendl;
- MDRequestRef mdr = request_start_internal(CEPH_MDS_OP_VALIDATE);
- filepath fp(path.c_str());
- mdr->set_filepath(fp);
- C_scrub_dentry_finish *csd = new C_scrub_dentry_finish(mdr, fin, f);
- mdr->internal_op_finish = csd;
- mdr->internal_op_private = &csd->results;
- scrub_dentry_work(mdr);
-}
-
-void MDCache::scrub_dentry_work(MDRequestRef& mdr)
-{
- set<SimpleLock*> rdlocks, wrlocks, xlocks;
- CInode *in = mds->server->rdlock_path_pin_ref(mdr, 0, rdlocks, true);
- if (NULL == in)
- return;
-
- // TODO: Remove this restriction
- assert(in->is_auth());
-
- bool locked = mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks);
- if (!locked)
- return;
-
- CInode::validated_data *vr =
- static_cast<CInode::validated_data*>(mdr->internal_op_private);
-
- in->validate_disk_state(vr, mdr, NULL);
- return;
-}
class C_MDS_EnqueueScrub : public Context
{
}
protected:
- /**
- * Scrub the named dentry only (skip the scrubstack)
- */
- void scrub_dentry_work(MDRequestRef& mdr);
void flush_dentry_work(MDRequestRef& mdr);
/**
* Resolve path to a dentry and pass it onto the ScrubStack.
void repair_dirfrag_stats_work(MDRequestRef& mdr);
friend class C_MDC_RepairDirfragStats;
public:
- void scrub_dentry(const string& path, Formatter *f, Context *fin);
void flush_dentry(const string& path, Context *fin);
/**
* Create and start an OP_ENQUEUE_SCRUB
dn->scrub_children_finished();
CInode *in = dn->get_projected_inode();
C_InodeValidated *fin = new C_InodeValidated(mdcache->mds, this, dn);
- MDRequestRef null_mdr;
- in->validate_disk_state(&fin->result, null_mdr, fin);
+ in->validate_disk_state(&fin->result, fin);
}
return;
// At this stage the DN is already past scrub_initialize, so
// it's in the cache, it has PIN_SCRUBQUEUE and it is authpinned
- MDRequestRef null_mdr;
- in->validate_disk_state(&fin->result, null_mdr, fin);
+ in->validate_disk_state(&fin->result, fin);
}
void ScrubStack::_validate_inode_done(CDentry *dn, int r,