From: John Spray Date: Thu, 16 Jul 2015 10:31:23 +0000 (+0100) Subject: mds: Hook ScrubStack into CInode::validate_disk_state X-Git-Tag: v10.0.1~51^2~10 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=ee822438283188a9a9f92e6704799db0433b3bd5;p=ceph.git mds: Hook ScrubStack into CInode::validate_disk_state Signed-off-by: John Spray --- diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index a5ceea4442a7..4ba3ca4a9ccc 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -3642,11 +3642,12 @@ void InodeStore::generate_test_instances(list &ls) } void CInode::validate_disk_state(CInode::validated_data *results, - MDRequestRef &mdr) + MDRequestRef &mdr, MDSInternalContext *fin) { class ValidationContinuation : public MDSContinuation { public: MDRequestRef mdr; + MDSInternalContext *fin; CInode *in; CInode::validated_data *results; bufferlist bl; @@ -3659,11 +3660,18 @@ void CInode::validate_disk_state(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) : + MDRequestRef &_mdr, + MDSInternalContext *fin_) : MDSContinuation(i->mdcache->mds->server), mdr(_mdr), + fin(fin_), in(i), results(data_r), shadow_in(NULL) { @@ -3850,14 +3858,19 @@ void CInode::validate_disk_state(CInode::validated_data *results, } void _done() { - server->respond_to_request(mdr, get_rval()); + if (mdr) { + server->respond_to_request(mdr, get_rval()); + } else if (fin) { + fin->complete(get_rval()); + } } }; ValidationContinuation *vc = new ValidationContinuation(this, results, - mdr); + mdr, + fin); vc->begin(); } diff --git a/src/mds/CInode.h b/src/mds/CInode.h index c77375544c9e..f032e5f54ddd 100644 --- a/src/mds/CInode.h +++ b/src/mds/CInode.h @@ -1095,10 +1095,12 @@ public: * @param results A freshly-created validated_data struct, with values set * as described in the struct documentation. * @param mdr The request to be responeded upon the completion of the - * validation. + * validation (or NULL) + * @param fin Context to call back on completion (or NULL) */ void validate_disk_state(validated_data *results, - MDRequestRef& mdr); + MDRequestRef& mdr, + MDSInternalContext *fin); static void dump_validation_results(const validated_data& results, Formatter *f); private: diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index e7889793f5c7..f87b78575880 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -11710,7 +11710,7 @@ void MDCache::scrub_dentry_work(MDRequestRef& mdr) CInode::validated_data *vr = static_cast(mdr->internal_op_private); - in->validate_disk_state(vr, mdr); + in->validate_disk_state(vr, mdr, NULL); return; } diff --git a/src/mds/ScrubStack.cc b/src/mds/ScrubStack.cc index c5abc86d44d8..b0a43520628b 100644 --- a/src/mds/ScrubStack.cc +++ b/src/mds/ScrubStack.cc @@ -367,14 +367,47 @@ void ScrubStack::scrub_dirfrag(CDir *dir, bool *added_children, } } +class C_InodeValidated : public MDSInternalContext +{ + public: + ScrubStack *stack; + CInode::validated_data result; + CDentry *target; + + C_InodeValidated(MDSRank *mds, ScrubStack *stack_, CDentry *target_) + : MDSInternalContext(mds), stack(stack_), target(target_) + {} + + void finish(int r) + { + stack->_scrub_file_dentry_done(target, r, result); + } +}; + void ScrubStack::scrub_file_dentry(CDentry *dn) { - // No-op: - // TODO: hook into validate_disk_state + assert(dn->get_linkage()->get_inode() != NULL); + + CInode *in = dn->get_linkage()->get_inode(); + C_InodeValidated *fin = new C_InodeValidated(mdcache->mds, this, dn); + + // 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); +} + +void ScrubStack::_scrub_file_dentry_done(CDentry *dn, int r, + const CInode::validated_data &result) +{ + // FIXME: do something real with result! DamageTable! Spamming + // the cluster log for debugging purposes + LogChannelRef clog = mdcache->mds->clog; + clog->info() << " scrubbed file dentry " << dn->name << " r=" << r; + Context *c = NULL; dn->scrub_finished(&c); if (c) { - // FIXME: pass some error code in? finisher->queue(new MDSIOContextWrapper(mdcache->mds, c), 0); } } diff --git a/src/mds/ScrubStack.h b/src/mds/ScrubStack.h index 14ae869be5a7..4c3563032b88 100644 --- a/src/mds/ScrubStack.h +++ b/src/mds/ScrubStack.h @@ -113,6 +113,17 @@ private: * @pre dn->get_projected_inode()->is_file()==true; */ void scrub_file_dentry(CDentry *dn); + + /** + * Callback from completion of CInode::validate_disk_state + * @param dn The dentry owning the inode we were validating + * @param r The return status from validate_disk_state + * @param result Populated results from validate_disk_state + */ + void _scrub_file_dentry_done(CDentry *dn, int r, + const CInode::validated_data &result); + friend class C_InodeValidated; + /** * Make progress on scrubbing a directory-representing dirfrag and * its children..