From: Yan, Zheng Date: Mon, 15 May 2017 02:19:18 +0000 (+0800) Subject: mds: properly update subtree map when merging dirfrags X-Git-Tag: v12.1.0~128^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=22369f441865934074d1ccdd7923f1c4a37df002;p=ceph.git mds: properly update subtree map when merging dirfrags After introducing auxiliary subtree, the source dirfrags for merging can be mixed with subtree dirfrags and non-subtreee dirfrags. If the resulting dirfrag is a subtree, we need to find any subtrees under the non-subtree source dirfrags and link them to the resulting dirfrag. Signed-off-by: "Yan, Zheng" --- diff --git a/src/mds/MDCache.cc b/src/mds/MDCache.cc index 59448528d9dd8..4136e8f68b6ad 100644 --- a/src/mds/MDCache.cc +++ b/src/mds/MDCache.cc @@ -10730,13 +10730,26 @@ void MDCache::adjust_dir_fragments(CInode *diri, // are my constituent bits subtrees? if so, i will be too. // (it's all or none, actually.) - bool was_subtree = false; - set new_bounds; - for (list::iterator p = srcfrags.begin(); p != srcfrags.end(); ++p) { - CDir *dir = *p; + bool any_subtree = false; + for (CDir *dir : srcfrags) { if (dir->is_subtree_root()) { + any_subtree = true; + break; + } + } + set new_bounds; + if (any_subtree) { + for (CDir *dir : srcfrags) { + // this simplifies the code that find subtrees underneath the dirfrag + if (!dir->is_subtree_root()) { + dir->state_set(CDir::STATE_AUXSUBTREE); + adjust_subtree_auth(dir, mds->get_nodeid()); + } + } + + for (CDir *dir : srcfrags) { + assert(dir->is_subtree_root()); dout(10) << " taking srcfrag subtree bounds from " << *dir << dendl; - was_subtree = true; map >::iterator q = subtrees.find(dir); set::iterator r = q->second.begin(); while (r != subtrees[dir].end()) { @@ -10744,7 +10757,7 @@ void MDCache::adjust_dir_fragments(CInode *diri, subtrees[dir].erase(r++); } subtrees.erase(q); - + // remove myself as my parent's bound if (parent_subtree) subtrees[parent_subtree].erase(dir); @@ -10756,7 +10769,7 @@ void MDCache::adjust_dir_fragments(CInode *diri, f->merge(srcfrags, waiters, replay); diri->add_dirfrag(f); - if (was_subtree) { + if (any_subtree) { assert(f->is_subtree_root()); subtrees[f].swap(new_bounds); if (parent_subtree)