]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: fix MDCache::adjust_bounded_subtree_auth()
authorYan, Zheng <zheng.z.yan@intel.com>
Tue, 12 Mar 2013 11:41:13 +0000 (19:41 +0800)
committerYan, Zheng <zheng.z.yan@intel.com>
Sun, 31 Mar 2013 08:57:14 +0000 (16:57 +0800)
There are cases that need both create new bound and swallow intervening
subtree. For example: A MDS exports subtree A with bound B and imports
subtree B with bound C at the same time. The MDS crashes, exporting
subtree A fails, but importing subtree B succeed. During recovery, the
MDS may create new bound C and swallow subtree B.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
Reviewed-by: Greg Farnum <greg@inktank.com>
src/mds/MDCache.cc

index 4bce73d18223f782cdf91546a7206ef27daa0579..dad2f49dd7b7f8bb02abac968e4698eea4c0540c 100644 (file)
@@ -984,15 +984,21 @@ void MDCache::adjust_bounded_subtree_auth(CDir *dir, set<CDir*>& bounds, pair<in
       }
       else {
        dout(10) << "  want bound " << *bound << dendl;
+       CDir *t = get_subtree_root(bound->get_parent_dir());
+       if (subtrees[t].count(bound) == 0) {
+         assert(t != dir);
+         dout(10) << "  new bound " << *bound << dendl;
+         adjust_subtree_auth(bound, t->authority());
+       }
        // make sure it's nested beneath ambiguous subtree(s)
        while (1) {
-         CDir *t = get_subtree_root(bound->get_parent_dir());
-         if (t == dir) break;
          while (subtrees[dir].count(t) == 0)
            t = get_subtree_root(t->get_parent_dir());
          dout(10) << "  swallowing intervening subtree at " << *t << dendl;
          adjust_subtree_auth(t, auth);
          try_subtree_merge_at(t);
+         t = get_subtree_root(bound->get_parent_dir());
+         if (t == dir) break;
        }
       }
     }