]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: skip journaling slave rename when possible
authorYan, Zheng <zheng.z.yan@intel.com>
Thu, 8 May 2014 07:14:43 +0000 (15:14 +0800)
committerYan, Zheng <zheng.z.yan@intel.com>
Sun, 18 May 2014 05:13:20 +0000 (13:13 +0800)
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 <zheng.z.yan@intel.com>
src/mds/CDentry.h
src/mds/MDLog.cc
src/mds/MDLog.h
src/mds/Server.cc
src/mds/events/EMetaBlob.h

index 1c32a0ac5db7bbefae316dd59531849e10a4d37d..7b545b54edccfd0324424d5e330a067ea964de74 100644 (file)
@@ -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())
index 7b4ba13f223ad14c9527b55fa905de473c16fd1d..d670d5af575fe44ba09d6b75a4058f49727bef04 100644 (file)
@@ -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());
index 6e8e980c94e94a62b991f8b1f8dd0ca03f6ad138..8aa645a69e6a63e2d6e6fb1a6f006599f2e35025 100644 (file)
@@ -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);
index 2cc972605285625706aa6faa0c3ed24affb9d531..9351fc6a6006b3f80511856e0b2a89abca70d942 100644 (file)
@@ -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<Context*> 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,
index 4d52b7fb73a70f887d64932009095f341ce7ad92..77c20db47f783bcded0fce92757fd5be54dd9d43 100644 (file)
@@ -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())