From: Yan, Zheng Date: Mon, 20 Mar 2017 03:36:18 +0000 (+0800) Subject: mds: proper trim stopping mds's mdsdir inode X-Git-Tag: v12.0.2~112^2~7 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=c4bfe3e3ffc1e8a8025c13a5c49063d3d41df1b5;p=ceph.git mds: proper trim stopping mds's mdsdir inode previous code does not work when only mdsdir inode is replicated (mdsdir dirfrag is not replicated) Signed-off-by: "Yan, Zheng" --- diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 029d9d0dc49e..74c87c4271eb 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -3649,42 +3649,36 @@ void MDCache::remove_inode_recursive(CInode *in) bool MDCache::expire_recursive( CInode *in, - map& expiremap, - CDir *subtree) + map& expiremap) { assert(!in->is_auth()); dout(10) << __func__ << ":" << *in << dendl; - mds_rank_t owner = subtree->dir_auth.first; - MCacheExpire *expire_msg = expiremap[owner]; - assert(expire_msg); - // Recurse into any dirfrags beneath this inode list ls; in->get_dirfrags(ls); - for (std::list::iterator p = ls.begin(); p != ls.end(); ++p) { - CDir *subdir = *p; + for (auto subdir : ls) { + if (!in->is_mdsdir() && subdir->is_subtree_root()) { + dout(10) << __func__ << ": stray still has subtree " << *in << dendl; + return true; + } - dout(10) << __func__ << ": entering dirfrag " << subdir << dendl; - for (CDir::map_t::iterator q = subdir->items.begin(); - q != subdir->items.end(); ++q) { - CDentry *dn = q->second; + for (auto &it : subdir->items) { + CDentry *dn = it.second; CDentry::linkage_t *dnl = dn->get_linkage(); if (dnl->is_primary()) { CInode *tin = dnl->get_inode(); - dout(10) << __func__ << ": tin=" - << *tin << dendl; /* Remote strays with linkage (i.e. hardlinks) should not be * expired, because they may be the target of * a rename() as the owning MDS shuts down */ - if (!tin->is_dir() && tin->inode.nlink) { - dout(10) << __func__ << ": child still has linkage" << dendl; + if (!tin->is_stray() && tin->inode.nlink) { + dout(10) << __func__ << ": stray still has linkage " << *tin << dendl; return true; } - const bool abort = expire_recursive(tin, expiremap, subtree); + const bool abort = expire_recursive(tin, expiremap); if (abort) { return true; } @@ -3692,7 +3686,7 @@ bool MDCache::expire_recursive( if (dn->lru_is_expireable()) { trim_dentry(dn, expiremap); } else { - dout(10) << __func__ << ": dn still has linkage " << *dn << dendl; + dout(10) << __func__ << ": stray dn is not expireable " << *dn << dendl; return true; } } @@ -6461,45 +6455,33 @@ bool MDCache::trim(int max, int count) trim_inode(0, root, 0, expiremap); } - // Trim remote stray dirs for stopping MDS ranks - std::list subtree_list; - list_subtrees(subtree_list); // Take copy because will modify in loop - for (std::list::iterator s = subtree_list.begin(); - s != subtree_list.end(); ++s) { - CDir *subtree = *s; - if (subtree->inode->is_mdsdir()) { - mds_rank_t owner = mds_rank_t(MDS_INO_MDSDIR_OWNER(subtree->inode->ino())); - if (owner == mds->get_nodeid() || !mds->mdsmap->is_up(owner)) { - continue; - } + std::set stopping; + mds->mdsmap->get_mds_set(stopping, MDSMap::STATE_STOPPING); + stopping.erase(mds->get_nodeid()); + for (auto rank : stopping) { + CInode* mdsdir_in = get_inode(MDS_INO_MDSDIR(rank)); + if (!mdsdir_in) + continue; - dout(20) << __func__ << ": checking remote MDS dir " << *(subtree) << dendl; + if (expiremap.count(rank) == 0) { + expiremap[rank] = new MCacheExpire(mds->get_nodeid()); + } - const MDSMap::mds_info_t &owner_info = mds->mdsmap->get_mds_info(owner); - if (owner_info.state == MDSMap::STATE_STOPPING) { - dout(20) << __func__ << ": it's stopping, remove it" << dendl; - if (expiremap.count(owner) == 0) { - expiremap[owner] = new MCacheExpire(mds->get_nodeid()); - } + dout(20) << __func__ << ": try expiring " << *mdsdir_in << " for stopping mds." << mds << dendl; - const bool aborted = expire_recursive( - subtree->inode, expiremap, subtree); - if (!aborted) { - dout(20) << __func__ << ": successfully expired mdsdir" << dendl; - CInode *subtree_in = subtree->inode; - list ls; - subtree->inode->get_dirfrags(ls); - for (std::list::iterator p = ls.begin(); p != ls.end(); ++p) { - CDir *frag = *p; - trim_dirfrag(frag, subtree, expiremap); - } - trim_inode(NULL, subtree_in, NULL, expiremap); - } else { - dout(20) << __func__ << ": some unexpirable contents in mdsdir" << dendl; - } - } else { - dout(20) << __func__ << ": not stopping, leaving it alone" << dendl; + const bool aborted = expire_recursive(mdsdir_in, expiremap); + if (!aborted) { + dout(20) << __func__ << ": successfully expired mdsdir" << dendl; + list ls; + mdsdir_in->get_dirfrags(ls); + for (auto dir : ls) { + if (dir->get_num_ref() == 1) // subtree pin + trim_dirfrag(dir, dir, expiremap); } + if (mdsdir_in->get_num_ref() == 0) + trim_inode(NULL, mdsdir_in, NULL, expiremap); + } else { + dout(20) << __func__ << ": some unexpirable contents in mdsdir" << dendl; } } diff --git a/src/mds/MDCache.h b/src/mds/MDCache.h index fbdb5005ce65..a1ef2283948e 100644 --- a/src/mds/MDCache.h +++ b/src/mds/MDCache.h @@ -694,8 +694,7 @@ public: */ bool expire_recursive( CInode *in, - std::map& expiremap, - CDir *subtree); + std::map& expiremap); void trim_client_leases(); void check_memory_usage();