From: Greg Farnum Date: Tue, 9 Sep 2014 21:55:42 +0000 (-0700) Subject: MDS: add a flush_dentry() function, and wire it up to the admin socket X-Git-Tag: v0.89~50^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=26736b2244e3b7b9a412660ddd5126628e23e7ab;p=ceph.git MDS: add a flush_dentry() function, and wire it up to the admin socket Signed-off-by: Greg Farnum --- diff --git a/src/include/ceph_fs.h b/src/include/ceph_fs.h index cf6148eee949..06d8f745d76c 100644 --- a/src/include/ceph_fs.h +++ b/src/include/ceph_fs.h @@ -340,7 +340,8 @@ enum { // internal op CEPH_MDS_OP_FRAGMENTDIR= 0x01500, CEPH_MDS_OP_EXPORTDIR = 0x01501, - CEPH_MDS_OP_VALIDATE = 0x01502 + CEPH_MDS_OP_VALIDATE = 0x01502, + CEPH_MDS_OP_FLUSH = 0x01503 }; extern const char *ceph_mds_op_name(int op); diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index c296fd4c0595..40de91d3ee9d 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -8485,6 +8485,9 @@ void MDCache::dispatch_request(MDRequestRef& mdr) case CEPH_MDS_OP_VALIDATE: scrub_dentry_work(mdr); break; + case CEPH_MDS_OP_FLUSH: + flush_dentry_work(mdr); + break; default: assert(0); } @@ -11556,3 +11559,28 @@ void MDCache::scrub_dentry_work(MDRequestRef& mdr) in->validate_disk_state(vr, mdr->internal_op_finish); return; } + +void MDCache::flush_dentry(const string& path, Context *fin) +{ + dout(10) << "flush_dentry " << path << dendl; + MDRequestRef mdr = request_start_internal(CEPH_MDS_OP_FLUSH); + filepath fp(path.c_str()); + mdr->set_filepath(fp); + mdr->internal_op_finish = fin; + flush_dentry_work(mdr); +} + +void MDCache::flush_dentry_work(MDRequestRef& mdr) +{ + set rdlocks, wrlocks, xlocks; + CInode *in = mds->server->rdlock_path_pin_ref(mdr, 0, rdlocks, true); + if (NULL == in) + return; + + // TODO: Is this necessary? Fix it if so + assert(in->is_auth()); + bool locked = mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks); + if (!locked) + return; + in->flush(new MDSInternalContextWrapper(mds,mdr->internal_op_finish)); +} diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h index d83b5aa8deeb..604708611ad7 100644 --- a/src/mds/MDCache.h +++ b/src/mds/MDCache.h @@ -1034,6 +1034,8 @@ public: } void scrub_dentry(const string& path, Formatter *f, Context *fin); void scrub_dentry_work(MDRequestRef& mdr); + void flush_dentry(const string& path, Context *fin); + void flush_dentry_work(MDRequestRef& mdr); }; class C_MDS_RetryRequest : public MDSInternalContext { diff --git a/src/mds/MDS.cc b/src/mds/MDS.cc index 74d81f1df44d..a0b7725fd017 100644 --- a/src/mds/MDS.cc +++ b/src/mds/MDS.cc @@ -290,6 +290,10 @@ bool MDS::asok_command(string command, cmdmap_t& cmdmap, string format, string path; cmd_getval(g_ceph_context, cmdmap, "path", path); command_scrub_path(f, path); + } else if (command == "flush_path") { + string path; + cmd_getval(g_ceph_context, cmdmap, "path", path); + command_flush_path(f, path); } f->flush(ss); delete f; @@ -307,6 +311,19 @@ void MDS::command_scrub_path(Formatter *f, const string& path) // scrub_dentry() finishers will dump the data for us; we're done! } +void MDS::command_flush_path(Formatter *f, const string& path) +{ + C_SaferCond scond; + { + Mutex::Locker l(mds_lock); + mdcache->flush_dentry(path, &scond); + } + int r = scond.wait(); + f->open_object_section("results"); + f->dump_int("return_code", r); + f->close_section(); // results +} + void MDS::set_up_admin_socket() { int r; @@ -326,6 +343,10 @@ void MDS::set_up_admin_socket() "scrub_path name=path,type=CephString", asok_hook, "scrub an inode and output results"); + r = admin_socket->register_command("flush_path", + "flush_path name=path,type=CephString", + asok_hook, + "flush an inode (and its dirfrags)"); assert(0 == r); r = admin_socket->register_command("session evict", "session evict name=client_id,type=CephString", diff --git a/src/mds/MDS.h b/src/mds/MDS.h index aac6e6760a94..67b6591e610e 100644 --- a/src/mds/MDS.h +++ b/src/mds/MDS.h @@ -376,6 +376,7 @@ private: void clean_up_admin_socket(); void check_ops_in_flight(); // send off any slow ops to monitor void command_scrub_path(Formatter *f, const string& path); + void command_flush_path(Formatter *f, const string& path); // config observer bits virtual const char** get_tracked_conf_keys() const; virtual void handle_conf_change(const struct md_config_t *conf,