]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: journal remote inode's projected parent
authorYan, Zheng <zheng.z.yan@intel.com>
Tue, 4 Dec 2012 08:09:48 +0000 (16:09 +0800)
committerSage Weil <sage@inktank.com>
Tue, 4 Dec 2012 22:50:14 +0000 (14:50 -0800)
Server::_rename_prepare() adds remote inode's parent instead of
projected parent to the journal. So during journal replay, the
journal entry for the rename operation will wrongly revert the
remote inode's projected rename. This issue can be reproduced by:

 touch file1
 ln file1 file2
 rm file1
 mv file2 file3

After journal replay, file1 reappears and directory's fragstat
gets corrupted.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
src/mds/Server.cc

index d5548a8493c453b4c1763d5d069647f2ba629b6f..022a0dff983e35b3aee883afd4dc7f0b633aabb1 100644 (file)
@@ -5681,9 +5681,10 @@ void Server::_rename_prepare(MDRequest *mdr,
     } else if (destdnl->is_remote()) {
       if (oldin->is_auth()) {
        // auth for targeti
-       metablob->add_dir_context(oldin->get_parent_dir());
-       mdcache->journal_cow_dentry(mdr, metablob, oldin->parent, CEPH_NOSNAP, 0, destdnl);
-       metablob->add_primary_dentry(oldin->parent, true, oldin);
+       metablob->add_dir_context(oldin->get_projected_parent_dir());
+       mdcache->journal_cow_dentry(mdr, metablob, oldin->get_projected_parent_dn(),
+                                   CEPH_NOSNAP, 0, destdnl);
+       metablob->add_primary_dentry(oldin->get_projected_parent_dn(), true, oldin);
       }
       if (destdn->is_auth()) {
        // auth for dn, not targeti
@@ -5702,10 +5703,10 @@ void Server::_rename_prepare(MDRequest *mdr,
 
       if (destdn->is_auth())
         metablob->add_remote_dentry(destdn, true, srcdnl->get_remote_ino(), srcdnl->get_remote_d_type());
-      if (srci->get_parent_dn()->is_auth()) { // it's remote
-       metablob->add_dir_context(srci->get_parent_dir());
-        mdcache->journal_cow_dentry(mdr, metablob, srci->get_parent_dn(), CEPH_NOSNAP, 0, srcdnl);
-       metablob->add_primary_dentry(srci->get_parent_dn(), true, srci);
+      if (srci->get_projected_parent_dn()->is_auth()) { // it's remote
+       metablob->add_dir_context(srci->get_projected_parent_dir());
+        mdcache->journal_cow_dentry(mdr, metablob, srci->get_projected_parent_dn(), CEPH_NOSNAP, 0, srcdnl);
+       metablob->add_primary_dentry(srci->get_projected_parent_dn(), true, srci);
       }
     } else {
       if (destdn->is_auth() && !destdnl->is_null())