diff mbox

[09/14] mds: take export lock set before sending MExportDirDiscover

Message ID 1355214660-26354-10-git-send-email-zheng.z.yan@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Yan, Zheng Dec. 11, 2012, 8:30 a.m. UTC
From: "Yan, Zheng" <zheng.z.yan@intel.com>

Migrator::export_dir() only check if it can lock the export lock set
but not take the lock set. So someone else can change the path to
the exporting dir and confuse Migrator::handle_export_discover().

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
---
 src/mds/Migrator.cc | 7 +++++++
 1 file changed, 7 insertions(+)
diff mbox

Patch

diff --git a/src/mds/Migrator.cc b/src/mds/Migrator.cc
index c157279..5db21cd 100644
--- a/src/mds/Migrator.cc
+++ b/src/mds/Migrator.cc
@@ -236,6 +236,8 @@  void Migrator::handle_mds_failure_or_stop(int who)
 	dir->unfreeze_tree();  // cancel the freeze
 	dir->auth_unpin(this);
 	export_state.erase(dir); // clean up
+	export_unlock(dir);
+	export_locks.erase(dir);
 	dir->state_clear(CDir::STATE_EXPORTING);
 	if (export_peer[dir] != who) // tell them.
 	  mds->send_message_mds(new MExportDirCancel(dir->dirfrag()), export_peer[dir]);
@@ -663,6 +665,8 @@  void Migrator::export_dir(CDir *dir, int dest)
     dout(7) << "export_dir can't rdlock needed locks, failing." << dendl;
     return;
   }
+  mds->locker->rdlock_take_set(locks);
+  export_locks[dir].swap(locks);
 
   // ok.
   assert(export_state.count(dir) == 0);
@@ -705,6 +709,9 @@  void Migrator::handle_export_discover_ack(MExportDirDiscoverAck *m)
       export_peer[dir] != m->get_source().num()) {
     dout(7) << "must have aborted" << dendl;
   } else {
+    // release locks to avoid deadlock
+    export_unlock(dir);
+    export_locks.erase(dir);
     // freeze the subtree
     export_state[dir] = EXPORT_FREEZING;
     dir->auth_unpin(this);