]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: fix rename common parent checks
authorSage Weil <sage@newdream.net>
Fri, 27 Mar 2009 17:53:00 +0000 (10:53 -0700)
committerSage Weil <sage@newdream.net>
Fri, 27 Mar 2009 19:54:39 +0000 (12:54 -0700)
Rewrite common parent logic in terms of base inodes, since the
traces may initially be empty, and we may be renaming items in the
root directory.

Also look at _projected_ parents, not current parents.

src/mds/CInode.cc
src/mds/CInode.h
src/mds/Server.cc
src/mds/snap.cc

index 17145fbe04a910ea645dcd0652d54f7f985054bb..fdf1142c381fa80ba8802c850bccd66a10e4b63c 100644 (file)
@@ -424,15 +424,14 @@ CInode *CInode::get_parent_inode()
   return NULL;
 }
 
-
-bool CInode::is_ancestor_of(CInode *other)
+bool CInode::is_projected_ancestor_of(CInode *other)
 {
   while (other) {
     if (other == this)
       return true;
-    if (!other->get_parent_dn())
+    if (!other->get_projected_parent_dn())
       break;
-    other = other->get_parent_dn()->get_dir()->get_inode();
+    other = other->get_projected_parent_dn()->get_dir()->get_inode();
   }
   return false;
 }
index c58e4c634f91fa72c93007303c88208ac24cdb69..f847540cc39c01c10d9cc058d8d7a8cbc77d2c1a 100644 (file)
@@ -376,7 +376,7 @@ private:
   }
 
   // -- misc -- 
-  bool is_ancestor_of(CInode *other);
+  bool is_projected_ancestor_of(CInode *other);
   void make_path_string(string& s, bool force=false, CDentry *use_parent=NULL);
   void make_path_string_projected(string& s);  
   void make_path(filepath& s);
index c453229e625a0d3c66680fc6fc3a300495fd2b08..036a25e0e11e7963056b3b15363f92b0e61d150b 100644 (file)
@@ -3502,22 +3502,28 @@ void Server::handle_client_rename(MDRequest *mdr)
     if (common) {
       dout(10) << "rename src and dest traces share common dentry " << *common << dendl;
     } else {
+      CInode *srcbase = srctrace[0]->get_dir()->get_inode();
+      CInode *destbase = destdir->get_inode();
+      if (!desttrace.empty())
+       destbase = desttrace[0]->get_dir()->get_inode();
+
       // ok, extend srctrace toward root until it is an ancestor of desttrace.
-      while (srctrace[0]->get_dir()->get_inode() != desttrace[0]->get_dir()->get_inode() &&
-            !srctrace[0]->get_dir()->get_inode()->is_ancestor_of(desttrace[0]->get_dir()->get_inode())) {
+      while (srcbase != destbase &&
+            !srcbase->is_projected_ancestor_of(destbase)) {
        srctrace.insert(srctrace.begin(),
-                       srctrace[0]->get_dir()->get_inode()->get_parent_dn());
+                       srcbase->get_projected_parent_dn());
        dout(10) << "rename prepending srctrace with " << *srctrace[0] << dendl;
+       srcbase = srcbase->get_projected_parent_dn()->get_dir()->get_inode();
       }
 
       // then, extend destpath until it shares the same parent inode as srcpath.
-      while (desttrace[0]->get_dir()->get_inode() != srctrace[0]->get_dir()->get_inode()) {
+      while (destbase != srcbase) {
        desttrace.insert(desttrace.begin(),
-                        desttrace[0]->get_dir()->get_inode()->get_parent_dn());
+                        destbase->get_projected_parent_dn());
        dout(10) << "rename prepending desttrace with " << *desttrace[0] << dendl;
+       destbase = destbase->get_projected_parent_dn()->get_dir()->get_inode();
       }
-      dout(10) << "rename src and dest traces now share common ancestor "
-              << *desttrace[0]->get_dir()->get_inode() << dendl;
+      dout(10) << "rename src and dest traces now share common ancestor " << *destbase << dendl;
     }
   }
 
index 7a041751fccdf0f3cd530d0855efff8ff0bc3e75..bc37ea56284fff69cd1f4b4ecdf2ca410e0c6553 100644 (file)
@@ -366,7 +366,7 @@ void SnapRealm::split_at(SnapRealm *child)
        p != open_children.end(); ) {
     SnapRealm *realm = *p;
     if (realm != child &&
-       child->inode->is_ancestor_of(realm->inode)) {
+       child->inode->is_projected_ancestor_of(realm->inode)) {
       dout(20) << " child gets child realm " << *realm << " on " << *realm->inode << dendl;
       realm->parent = child;
       child->open_children.insert(realm);