From 3e691d3181f4e897b456f8bae08ec6d3d346fe3a Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 23 Feb 2011 14:25:06 -0800 Subject: [PATCH] mds: fix export cancellation vs nested freezes Prevent freezes from completing while we are canceling exports. Otherwise if we are freezing /a/b and /a, and cancel /a/b, we may inadvertantly complete the freeze on /a (synchronously) and confuse ourselves. Pin all freezes beforehand so that when we cancel each one we do not cause any others to prematurely complete. Signed-off-by: Sage Weil --- src/mds/Migrator.cc | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/mds/Migrator.cc b/src/mds/Migrator.cc index 0db6879a924bb..5711cf2c5e49f 100644 --- a/src/mds/Migrator.cc +++ b/src/mds/Migrator.cc @@ -178,6 +178,24 @@ void Migrator::handle_mds_failure_or_stop(int who) dout(5) << "handle_mds_failure_or_stop mds" << who << dendl; // check my exports + + // first add an extra auth_pin on any freezes, so that canceling a + // nested freeze doesn't complete one further up the hierarchy and + // confuse the shit out of us. we'll remove it after canceling the + // freeze. this way no freeze completions run before we want them + // to. + list pinned_dirs; + for (map::iterator p = export_state.begin(); + p != export_state.end(); + ++p) { + if (p->second == EXPORT_FREEZING) { + CDir *dir = p->first; + dout(10) << "adding temp auth_pin on freezing " << *dir << dendl; + dir->auth_pin(this); + pinned_dirs.push_back(dir); + } + } + map::iterator p = export_state.begin(); while (p != export_state.end()) { map::iterator next = p; @@ -411,6 +429,13 @@ void Migrator::handle_mds_failure_or_stop(int who) // next! q = next; } + + while (!pinned_dirs.empty()) { + CDir *dir = pinned_dirs.front(); + dout(10) << "removing temp auth_pin on " << *dir << dendl; + dir->auth_unpin(this); + pinned_dirs.pop_front(); + } } -- 2.39.5