From: Yan, Zheng Date: Wed, 22 Nov 2017 03:49:43 +0000 (+0800) Subject: mds: ignore export pin for unlinked directory X-Git-Tag: v12.2.3~143^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=443fa3546593f667b01cca7466e3692223c4f226;p=ceph.git mds: ignore export pin for unlinked directory Otherwise, stray directory inode may have pinned subtree dirfrag. The subtree dirfrag prevents stray inode from getting purged. Fixes: http://tracker.ceph.com/issues/22219 Signed-off-by: "Yan, Zheng" (cherry picked from commit b7cee60467582d7398bbe85e051a722e30c0897e) --- diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index 633e6477553d..0184480ae847 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -4494,12 +4494,23 @@ mds_rank_t CInode::get_export_pin(bool inherit) const * N.B. inodes not yet linked into a dir (i.e. anonymous inodes) will not * have a parent yet. */ - for (const CInode *in = this; !in->is_base() && !in->is_system() && in->get_projected_parent_dn(); in = in->get_projected_parent_dn()->dir->inode) { - mds_rank_t pin = in->get_projected_inode()->export_pin; - if (pin >= 0) { - return pin; - } - if (!inherit) break; + const CInode *in = this; + while (true) { + if (in->is_system()) + break; + const CDentry *pdn = in->get_projected_parent_dn(); + if (!pdn) + break; + const inode_t *pi = in->get_projected_inode(); + // ignore export pin for unlinked directory + if (pi->nlink == 0) + break; + if (pi->export_pin >= 0) + return pi->export_pin; + + if (!inherit) + break; + in = pdn->get_dir()->inode; } return MDS_RANK_NONE; } diff --git a/src/mds/Migrator.cc b/src/mds/Migrator.cc index 6603e4f1a966..41fe12795139 100644 --- a/src/mds/Migrator.cc +++ b/src/mds/Migrator.cc @@ -798,10 +798,17 @@ void Migrator::export_dir(CDir *dir, mds_rank_t dest) return; } - if (!dir->inode->is_base() && dir->inode->get_projected_parent_dir()->inode->is_stray() && - dir->inode->get_projected_parent_dir()->get_parent_dir()->ino() != MDS_INO_MDSDIR(dest)) { - dout(7) << "i won't export anything in stray" << dendl; - return; + CDir* parent_dir = dir->inode->get_projected_parent_dir(); + if (parent_dir && parent_dir->inode->is_stray()) { + if (parent_dir->get_parent_dir()->ino() != MDS_INO_MDSDIR(dest)) { + dout(7) << "i won't export anything in stray" << dendl; + return; + } + } else { + if (!mds->is_stopping() && !dir->inode->is_exportable(dest)) { + dout(7) << "dir is export pinned" << dendl; + return; + } } if (dir->is_frozen() || @@ -813,12 +820,6 @@ void Migrator::export_dir(CDir *dir, mds_rank_t dest) dout(7) << "already exporting" << dendl; return; } - - if (!mds->is_stopping() && !dir->inode->is_exportable(dest)) { - dout(7) << "dir is export pinned" << dendl; - return; - } - if (dest == mds->get_nodeid() || !mds->mdsmap->is_up(dest)) { dout(7) << "cannot export: dest " << dest << " is me or is not active" << dendl; return; diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 38c44523e95c..06c0b1d189ef 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -5987,6 +5987,8 @@ void Server::_unlink_local(MDRequestRef& mdr, CDentry *dn, CDentry *straydn) if (in->is_dir()) { assert(straydn); mdcache->project_subtree_rename(in, dn->get_dir(), straydn->get_dir()); + + in->maybe_export_pin(true); } journal_and_reply(mdr, 0, dn, le, new C_MDS_unlink_local_finish(this, mdr, dn, straydn));