From da12abbd0f07fe05dbdf4c0971a5a1fffbd03b4b Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Mon, 7 Aug 2017 15:23:18 +0800 Subject: [PATCH] mds: fix CInode::find_snaprealm() If inode has no parent dentry (newly created), CInode::find_snaprealm() should try the oldest projected parent. Signed-off-by: "Yan, Zheng" --- src/mds/CInode.cc | 32 ++++++++++++++++++++++++-------- src/mds/CInode.h | 10 ++++++++-- src/mds/SnapRealm.cc | 25 ++++--------------------- 3 files changed, 36 insertions(+), 31 deletions(-) diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 581ae2d0d91..4ba7a6f12f8 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -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; } diff --git a/src/mds/CInode.h b/src/mds/CInode.h index 01c942c9cf5..be6ecd7c1f5 100644 --- a/src/mds/CInode.h +++ b/src/mds/CInode.h @@ -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; diff --git a/src/mds/SnapRealm.cc b/src/mds/SnapRealm.cc index df5cb12df7f..55bc49cb731 100644 --- a/src/mds/SnapRealm.cc +++ b/src/mds/SnapRealm.cc @@ -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::iterator p = inodes_with_caps.begin(member_offset(CInode, item_caps)); - while (!p.end()) { + for (elist::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 { -- 2.39.5