From: Yan, Zheng Date: Thu, 8 May 2014 07:14:43 +0000 (+0800) Subject: mds: skip journaling slave rename when possible X-Git-Tag: v0.82~56^2~6 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=6fe7d175f2bbee3e49f5c26ecf42431f5e26bb08;p=ceph.git mds: skip journaling slave rename when possible Rename operation can affect three dentries and two inodes. For MDS who receives rename slave request, but isn't authority of any of these dentries/inodes and doesn't have any auth subtree under these dentries/inodes, journaling slave rename can be skipped. Signed-off-by: Yan, Zheng --- diff --git a/src/mds/CDentry.h b/src/mds/CDentry.h index 1c32a0ac5db7..7b545b54edcc 100644 --- a/src/mds/CDentry.h +++ b/src/mds/CDentry.h @@ -226,7 +226,7 @@ public: void push_projected_linkage(CInode *inode); linkage_t *pop_projected_linkage(); - bool is_projected() { return projected.size(); } + bool is_projected() { return !projected.empty(); } linkage_t *get_projected_linkage() { if (!projected.empty()) diff --git a/src/mds/MDLog.cc b/src/mds/MDLog.cc index 7b4ba13f223a..d670d5af575f 100644 --- a/src/mds/MDLog.cc +++ b/src/mds/MDLog.cc @@ -164,6 +164,13 @@ void MDLog::start_entry(LogEvent *e) e->set_start_off(get_write_pos()); } +void MDLog::cancel_entry(LogEvent *le) +{ + assert(le == cur_event); + cur_event = NULL; + delete le; +} + void MDLog::submit_entry(LogEvent *le, Context *c) { assert(!mds->is_any_replay()); diff --git a/src/mds/MDLog.h b/src/mds/MDLog.h index 6e8e980c94e9..8aa645a69e6a 100644 --- a/src/mds/MDLog.h +++ b/src/mds/MDLog.h @@ -202,6 +202,7 @@ private: LogEvent *cur_event; public: void start_entry(LogEvent *e); + void cancel_entry(LogEvent *e); void submit_entry(LogEvent *e, Context *c = 0); void start_submit_entry(LogEvent *e, Context *c = 0) { start_entry(e); diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 2cc972605285..9351fc6a6006 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -6285,6 +6285,9 @@ void Server::_rename_apply(MDRequestRef& mdr, CDentry *srcdn, CDentry *destdn, C destdn->get_dir()->unlink_inode(destdn); straydn->pop_projected_linkage(); + if (mdr->is_slave() && !mdr->more()->slave_update_journaled) + assert(!straydn->is_projected()); // no other projected + mdcache->touch_dentry_bottom(straydn); // drop dn as quickly as possible. // nlink-- targeti @@ -6316,6 +6319,8 @@ void Server::_rename_apply(MDRequestRef& mdr, CDentry *srcdn, CDentry *destdn, C if (!linkmerge) { // destdn destdnl = destdn->pop_projected_linkage(); + if (mdr->is_slave() && !mdr->more()->slave_update_journaled) + assert(!destdn->is_projected()); // no other projected destdn->link_remote(destdnl, in); if (destdn->is_auth()) @@ -6333,6 +6338,8 @@ void Server::_rename_apply(MDRequestRef& mdr, CDentry *srcdn, CDentry *destdn, C destdn->get_dir()->unlink_inode(destdn); } destdnl = destdn->pop_projected_linkage(); + if (mdr->is_slave() && !mdr->more()->slave_update_journaled) + assert(!destdn->is_projected()); // no other projected // srcdn inode import? if (!srcdn->is_auth() && destdn->is_auth()) { @@ -6381,6 +6388,8 @@ void Server::_rename_apply(MDRequestRef& mdr, CDentry *srcdn, CDentry *destdn, C if (srcdn->is_auth()) srcdn->mark_dirty(mdr->more()->pvmap[srcdn], mdr->ls); srcdn->pop_projected_linkage(); + if (mdr->is_slave() && !mdr->more()->slave_update_journaled) + assert(!srcdn->is_projected()); // no other projected // apply remaining projected inodes (nested) mdr->apply(); @@ -6629,11 +6638,18 @@ void Server::handle_slave_rename_prep(MDRequestRef& mdr) bufferlist blah; // inode import data... obviously not used if we're the slave _rename_prepare(mdr, &le->commit, &blah, srcdn, destdn, straydn); - - submit_mdlog_entry(le,new C_MDS_SlaveRenamePrep(this, mdr, - srcdn, destdn, straydn), - mdr, __func__); - mdlog->flush(); + + if (le->commit.empty()) { + dout(10) << " empty metablob, skipping journal" << dendl; + mdlog->cancel_entry(le); + mdr->ls = NULL; + _logged_slave_rename(mdr, srcdn, destdn, straydn); + } else { + mdr->more()->slave_update_journaled = true; + submit_mdlog_entry(le, new C_MDS_SlaveRenamePrep(this, mdr, srcdn, destdn, straydn), + mdr, __func__); + mdlog->flush(); + } } void Server::_logged_slave_rename(MDRequestRef& mdr, @@ -6717,12 +6733,6 @@ void Server::_commit_slave_rename(MDRequestRef& mdr, int r, list finished; if (r == 0) { - // write a commit to the journal - ESlaveUpdate *le = new ESlaveUpdate(mdlog, "slave_rename_commit", mdr->reqid, - mdr->slave_to_mds, ESlaveUpdate::OP_COMMIT, - ESlaveUpdate::RENAME); - mdlog->start_entry(le); - // unfreeze+singleauth inode // hmm, do i really need to delay this? if (mdr->more()->is_inode_exporter) { @@ -6765,8 +6775,17 @@ void Server::_commit_slave_rename(MDRequestRef& mdr, int r, mds->queue_waiters(finished); mdr->cleanup(); - submit_mdlog_entry(le, new C_MDS_CommittedSlave(this, mdr), mdr, __func__); - mdlog->flush(); + if (mdr->more()->slave_update_journaled) { + // write a commit to the journal + ESlaveUpdate *le = new ESlaveUpdate(mdlog, "slave_rename_commit", mdr->reqid, + mdr->slave_to_mds, ESlaveUpdate::OP_COMMIT, + ESlaveUpdate::RENAME); + mdlog->start_entry(le); + submit_mdlog_entry(le, new C_MDS_CommittedSlave(this, mdr), mdr, __func__); + mdlog->flush(); + } else { + _committed_slave(mdr); + } } else { // abort @@ -7059,12 +7078,20 @@ void Server::do_rename_rollback(bufferlist &rbl, int master, MDRequestRef& mdr, mdcache->project_subtree_rename(in, destdir, srcdir); } - submit_mdlog_entry(le, - new C_MDS_LoggedRenameRollback(this, mut, mdr, srcdn, - srcdnpv, destdn, - straydn, finish_mdr), - mdr, __func__); - mdlog->flush(); + if (mdr && !mdr->more()->slave_update_journaled) { + assert(le->commit.empty()); + mdlog->cancel_entry(le); + mut->ls = NULL; + _rename_rollback_finish(mut, mdr, srcdn, srcdnpv, destdn, straydn, finish_mdr); + } else { + assert(!le->commit.empty()); + if (mdr) + mdr->more()->slave_update_journaled = false; + Context *fin = new C_MDS_LoggedRenameRollback(this, mut, mdr, srcdn, srcdnpv, + destdn, straydn, finish_mdr); + submit_mdlog_entry(le, fin, mdr, __func__); + mdlog->flush(); + } } void Server::_rename_rollback_finish(MutationRef& mut, MDRequestRef& mdr, CDentry *srcdn, diff --git a/src/mds/events/EMetaBlob.h b/src/mds/events/EMetaBlob.h index 4d52b7fb73a7..77c20db47f78 100644 --- a/src/mds/events/EMetaBlob.h +++ b/src/mds/events/EMetaBlob.h @@ -534,6 +534,13 @@ private: void add_dir_context(CDir *dir, int mode = TO_AUTH_SUBTREE_ROOT); + bool empty() { + return roots.empty() && lump_order.empty() && table_tids.empty() && + truncate_start.empty() && truncate_finish.empty() && + destroyed_inodes.empty() && client_reqs.empty() && + opened_ino == 0 && inotablev == 0 && sessionmapv == 0; + } + void print(ostream& out) const { out << "[metablob"; if (!lump_order.empty())