]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: note subtree bounds when rolling back rename
authorYan, Zheng <zyan@redhat.com>
Thu, 9 Feb 2017 03:43:57 +0000 (11:43 +0800)
committerYan, Zheng <zyan@redhat.com>
Mon, 20 Feb 2017 08:12:36 +0000 (16:12 +0800)
mds can do a slave rename that moves directory inode (whoes dirfrags
are all non-auth) to new auth. Then rolls back the slave rename. If
There is a ESubtreeMap event between log event of slave rename and
log event of rollback. The ESubtreeMap does not have information
about the inode's non-auth dirfrags.

Later when mds replays the log, the log event of slave rename can
be missing. So mds need to re-create subtree bounds when replaying
the log event of rename rollback

Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
src/mds/Server.cc

index a8e1ec63e783d2e67bedb94de9cde6e5ff2fa180..9b9e730e2c096bffa210264208535baceb0edd3e 100644 (file)
@@ -7817,12 +7817,22 @@ void Server::do_rename_rollback(bufferlist &rbl, mds_rank_t master, MDRequestRef
     le->commit.add_primary_dentry(target->get_projected_parent_dn(), target, true);
   }
 
-  if (force_journal_dest) {
-    dout(10) << " noting rename target ino " << target->ino() << " in metablob" << dendl;
-    le->commit.renamed_dirino = target->ino();
-  } else if (force_journal_src || (in && in->is_dir() && srcdn->authority().first == whoami)) {
+  if (in && in->is_dir() && (srcdn->authority().first == whoami || force_journal_src)) {
     dout(10) << " noting renamed dir ino " << in->ino() << " in metablob" << dendl;
     le->commit.renamed_dirino = in->ino();
+    if (srcdn->authority().first == whoami) {
+      list<CDir*> ls;
+      in->get_dirfrags(ls);
+      for (list<CDir*>::iterator p = ls.begin(); p != ls.end(); ++p) {
+       CDir *dir = *p;
+       if (!dir->is_auth())
+         le->commit.renamed_dir_frags.push_back(dir->get_frag());
+      }
+      dout(10) << " noting renamed dir open frags " << le->commit.renamed_dir_frags << dendl;
+    }
+  } else if (force_journal_dest) {
+    dout(10) << " noting rename target ino " << target->ino() << " in metablob" << dendl;
+    le->commit.renamed_dirino = target->ino();
   }
   
   if (target && target->is_dir()) {