]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: fix CInode::find_snaprealm()
authorYan, Zheng <zyan@redhat.com>
Mon, 7 Aug 2017 07:23:18 +0000 (15:23 +0800)
committerYan, Zheng <zyan@redhat.com>
Mon, 4 Dec 2017 04:01:18 +0000 (12:01 +0800)
If inode has no parent dentry (newly created), CInode::find_snaprealm()
should try the oldest projected parent.

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

index 581ae2d0d91505eb098ffc33ec0be194553f6452..4ba7a6f12f840a6dc06af2e018d9b62ba356f1f8 100644 (file)
@@ -809,14 +809,32 @@ CInode *CInode::get_parent_inode()
   return NULL;
 }
 
-bool CInode::is_projected_ancestor_of(CInode *other)
+bool CInode::is_ancestor_of(const CInode *other) const
 {
   while (other) {
     if (other == this)
       return true;
-    if (!other->get_projected_parent_dn())
+    const CDentry *pdn = other->get_oldest_parent_dn();
+    if (!pdn) {
+      assert(other->is_base());
       break;
-    other = other->get_projected_parent_dn()->get_dir()->get_inode();
+    }
+    other = pdn->get_dir()->get_inode();
+  }
+  return false;
+}
+
+bool CInode::is_projected_ancestor_of(const CInode *other) const
+{
+  while (other) {
+    if (other == this)
+      return true;
+    const CDentry *pdn = other->get_projected_parent_dn();
+    if (!pdn) {
+      assert(other->is_base());
+      break;
+    }
+    other = pdn->get_dir()->get_inode();
   }
   return false;
 }
@@ -2661,12 +2679,10 @@ SnapRealm *CInode::find_snaprealm() const
 {
   const CInode *cur = this;
   while (!cur->snaprealm) {
-    if (cur->get_parent_dn())
-      cur = cur->get_parent_dn()->get_dir()->get_inode();
-    else if (get_projected_parent_dn())
-      cur = cur->get_projected_parent_dn()->get_dir()->get_inode();
-    else
+    const CDentry *pdn = cur->get_oldest_parent_dn();
+    if (!pdn)
       break;
+    cur = pdn->get_dir()->get_inode();
   }
   return cur->snaprealm;
 }
index 01c942c9cf533e6fa48f59d8cc94af966026948d..be6ecd7c1f599c50edc318702cdd00cc2b2bc040 100644 (file)
@@ -727,8 +727,13 @@ public:
   inode_t& get_inode() { return inode; }
   CDentry* get_parent_dn() { return parent; }
   const CDentry* get_parent_dn() const { return parent; }
-  const CDentry* get_projected_parent_dn() const { return !projected_parent.empty() ? projected_parent.back() : parent; }
   CDentry* get_projected_parent_dn() { return !projected_parent.empty() ? projected_parent.back() : parent; }
+  const CDentry* get_projected_parent_dn() const { return !projected_parent.empty() ? projected_parent.back() : parent; }
+  const CDentry* get_oldest_parent_dn() const {
+    if (parent)
+      return parent;
+    return !projected_parent.empty() ? projected_parent.front(): NULL;
+  }
   CDir *get_parent_dir();
   const CDir *get_projected_parent_dir() const;
   CDir *get_projected_parent_dir();
@@ -741,7 +746,8 @@ public:
   }
 
   // -- misc -- 
-  bool is_projected_ancestor_of(CInode *other);
+  bool is_ancestor_of(const CInode *other) const;
+  bool is_projected_ancestor_of(const CInode *other) const;
 
   void make_path_string(std::string& s, bool projected=false, const CDentry *use_parent=NULL) const;
   void make_path(filepath& s, bool projected=false) const;
index df5cb12df7faea2f60d0e9bf4250dfcd4ae5b190..55bc49cb7318cd0490a95d1544a9b7443a4fd711 100644 (file)
@@ -455,7 +455,7 @@ void SnapRealm::split_at(SnapRealm *child)
        p != open_children.end(); ) {
     SnapRealm *realm = *p;
     if (realm != child &&
-       child->inode->is_projected_ancestor_of(realm->inode)) {
+       child->inode->is_ancestor_of(realm->inode)) {
       dout(20) << " child gets child realm " << *realm << " on " << *realm->inode << dendl;
       realm->parent = child;
       child->open_children.insert(realm);
@@ -467,29 +467,12 @@ void SnapRealm::split_at(SnapRealm *child)
   }
 
   // split inodes_with_caps
-  elist<CInode*>::iterator p = inodes_with_caps.begin(member_offset(CInode, item_caps));
-  while (!p.end()) {
+  for (elist<CInode*>::iterator p = inodes_with_caps.begin(member_offset(CInode, item_caps));
+       !p.end(); ) {
     CInode *in = *p;
     ++p;
-
     // does inode fall within the child realm?
-    bool under_child = false;
-
-    if (in == child->inode) {
-      under_child = true;
-    } else {
-      CInode *t = in;
-      while (t->get_parent_dn()) {
-       t = t->get_parent_dn()->get_dir()->get_inode();
-       if (t == child->inode) {
-         under_child = true;
-         break;
-       }
-       if (t == in)
-         break;
-      }
-    }
-    if (under_child) {
+    if (child->inode->is_ancestor_of(in)) {
       dout(20) << " child gets " << *in << dendl;
       in->move_to_realm(child);
     } else {