From 23167ad552b999d0bf704310c2f6af445ff6f1f7 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 27 Mar 2009 10:53:00 -0700 Subject: [PATCH] mds: fix rename common parent checks 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 | 7 +++---- src/mds/CInode.h | 2 +- src/mds/Server.cc | 20 +++++++++++++------- src/mds/snap.cc | 2 +- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 17145fbe04a91..fdf1142c381fa 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -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; } diff --git a/src/mds/CInode.h b/src/mds/CInode.h index c58e4c634f91f..f847540cc39c0 100644 --- a/src/mds/CInode.h +++ b/src/mds/CInode.h @@ -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); diff --git a/src/mds/Server.cc b/src/mds/Server.cc index c453229e625a0..036a25e0e11e7 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -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; } } diff --git a/src/mds/snap.cc b/src/mds/snap.cc index 7a041751fccdf..bc37ea56284ff 100644 --- a/src/mds/snap.cc +++ b/src/mds/snap.cc @@ -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); -- 2.39.5