]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
fixed up freezing.. not it takes an auth_pin and is just better
authorsageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Thu, 9 Aug 2007 19:18:32 +0000 (19:18 +0000)
committersageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Thu, 9 Aug 2007 19:18:32 +0000 (19:18 +0000)
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1608 29311d96-e01e-0410-9327-a35deaab8ce9

branches/sage/mds/mds/CDir.cc
branches/sage/mds/mds/CDir.h
branches/sage/mds/mds/CInode.h
branches/sage/mds/mds/MDCache.cc
branches/sage/mds/mds/Migrator.cc

index 0847e867879d40387152b60909672fad5fb67116..e91e1b48b84db7fac68adcfbd5119b9599c3f054 100644 (file)
@@ -1322,8 +1322,10 @@ void CDir::auth_unpin()
   assert(auth_pins >= 0);
   
   // pending freeze?
-  if (auth_pins + nested_auth_pins == 0) 
-    on_freezeable();
+  if (state_test(STATE_FREEZINGTREE|STATE_FREEZINGDIR) &&
+      auth_pins == 1 && 
+      nested_auth_pins == 0) 
+    finish_waiting(WAIT_FREEZEABLE);
   
   // nest?
   if (is_subtree_root()) return;  // no.
@@ -1341,9 +1343,10 @@ void CDir::adjust_nested_auth_pins(int inc)
   assert(nested_auth_pins >= 0);
   
   // pending freeze?
-  if (is_freezeable())
-    on_freezeable();
-  // on freezeable_dir too?  FIXME
+  if (state_test(STATE_FREEZINGTREE|STATE_FREEZINGDIR) &&
+      auth_pins == 1 && 
+      nested_auth_pins == 0) 
+    finish_waiting(WAIT_FREEZEABLE);
   
   // adjust my inode?
   if (is_subtree_root()) 
@@ -1359,21 +1362,6 @@ void CDir::adjust_nested_auth_pins(int inc)
  * FREEZING
  */
 
-void CDir::on_freezeable()
-{
-  // check for anything pending freezeable
-
-  /* NOTE: this will be called on deeper dirs first, walking up toward
-     the root, meaning that deeper freeze attempts will succeed first.
-  */
-  /* NOTE: the first of these will likely freeze the dir, and unmark
-     FREEZING.  additional ones will re-flag FREEZING.  this isn't
-     particularly graceful, and might cause problems if the first one
-     needs to know about other waiters.... FIXME? */
-  
-  finish_waiting(WAIT_FREEZEABLE);
-}
-
 // FREEZE TREE
 
 class C_MDS_FreezeTree : public Context {
@@ -1393,24 +1381,29 @@ void CDir::freeze_tree(Context *c)
 {
   assert(!is_frozen());
   assert(!is_freezing());
+
+  auth_pin();
   
   if (is_freezeable()) {
-    _freeze_tree(c);
+    _freeze_tree();
+    auth_unpin();
+    if (c) {
+      c->finish(0);
+      delete c;
+    }
   } else {
     state_set(STATE_FREEZINGTREE);
-    dout(10) << "freeze_tree + wait " << *this << endl;
-    
-    // need to wait for auth pins to expire
+    dout(10) << "freeze_tree waiting " << *this << endl;
     add_waiter(WAIT_FREEZEABLE, new C_MDS_FreezeTree(this, c));
   } 
 }
 
-void CDir::_freeze_tree(Context *c)
+void CDir::_freeze_tree()
 {
   dout(10) << "_freeze_tree " << *this << endl;
 
-  // there shouldn't be any conflicting auth_pins.
-  assert(is_freezeable_dir());
+  // there shouldn't be any conflicting auth_pins (except the 'freezing' one)
+  assert(is_freezeable(true));
 
   // twiddle state
   state_clear(STATE_FREEZINGTREE);   // actually, this may get set again by next context?
@@ -1419,13 +1412,7 @@ void CDir::_freeze_tree(Context *c)
 
   // auth_pin inode for duration of freeze, if we are not a subtree root.
   if (is_auth() && !is_subtree_root())
-    inode->auth_pin();  
-  
-  // continue to frozen land
-  if (c) {
-    c->finish(0);
-    delete c;
-  }
+    inode->auth_pin();
 }
 
 void CDir::freeze_tree_finish(Context *c)
@@ -1439,16 +1426,20 @@ void CDir::freeze_tree_finish(Context *c)
   }
 
   // freezeable now?
-  if (!is_freezeable()) {
-    // wait again!
+  if (!is_freezeable(true)) {
     dout(10) << "freeze_tree_finish still waiting " << *this << endl;
-    state_set(STATE_FREEZINGTREE);
+    assert(state_test(STATE_FREEZINGTREE));
     add_waiter(WAIT_FREEZEABLE, new C_MDS_FreezeTree(this, c));
     return;
   }
 
   dout(10) << "freeze_tree_finish " << *this << endl;
-  _freeze_tree(c);
+  _freeze_tree();
+  auth_unpin();
+  if (c) {
+    c->finish(0);
+    delete c;
+  }
 }
 
 void CDir::unfreeze_tree()
@@ -1470,6 +1461,7 @@ void CDir::unfreeze_tree()
     // freezing.  stop it.
     assert(state_test(STATE_FREEZINGTREE));
     state_clear(STATE_FREEZINGTREE);
+    auth_unpin();
     
     // cancel freeze waiters
     finish_waiting(WAIT_UNFREEZE);
@@ -1539,32 +1531,33 @@ void CDir::freeze_dir(Context *c)
   assert(!is_frozen());
   assert(!is_freezing());
   
+  auth_pin();
   if (is_freezeable_dir()) {
-    _freeze_dir(c);
+    _freeze_dir();
+    auth_unpin();
+    if (c) {
+      c->finish(0);
+      delete c;
+    }
   } else {
     state_set(STATE_FREEZINGDIR);
     dout(10) << "freeze_dir + wait " << *this << endl;
-    
-    // need to wait for auth pins to expire
     add_waiter(WAIT_FREEZEABLE, new C_MDS_FreezeDir(this, c));
   } 
 }
 
-void CDir::_freeze_dir(Context *c)
+void CDir::_freeze_dir()
 {  
   dout(10) << "_freeze_dir " << *this << endl;
 
+  assert(is_freezeable_dir(true));
+
   state_clear(STATE_FREEZINGDIR);
   state_set(STATE_FROZENDIR);
   get(PIN_FROZEN);
 
   if (is_auth() && !is_subtree_root())
     inode->auth_pin();  // auth_pin for duration of freeze
-  
-  if (c) {
-    c->finish(0);
-    delete c;
-  }
 }
 
 void CDir::freeze_dir_finish(Context *c)
@@ -1578,8 +1571,7 @@ void CDir::freeze_dir_finish(Context *c)
   }
 
   // freezeable now?
-  if (!is_freezeable_dir()) {
-    // wait again!
+  if (!is_freezeable_dir(true)) {
     dout(10) << "freeze_dir_finish still waiting " << *this << endl;
     state_set(STATE_FREEZINGDIR);
     add_waiter(WAIT_FREEZEABLE, new C_MDS_FreezeDir(this, c));
@@ -1587,7 +1579,13 @@ void CDir::freeze_dir_finish(Context *c)
   }
 
   // freeze now
-  _freeze_dir(c);
+  dout(10) << "freeze_dir_finish " << *this << endl;
+  _freeze_dir();
+  auth_unpin();
+  if (c) {
+    c->finish(0);
+    delete c;
+  }
 }
 
 void CDir::unfreeze_dir()
@@ -1608,6 +1606,7 @@ void CDir::unfreeze_dir()
     // still freezing. stop.
     assert(state_test(STATE_FREEZINGDIR));
     state_clear(STATE_FREEZINGDIR);
+    auth_unpin();
     
     // cancel freeze waiters
     finish_waiting(WAIT_UNFREEZE);
index 1a0dbe2af0d2c2eb749e1c372b4454927f46d9d3..e4ac2f2a5c82f47e8d62e3406f9dc12938c7bc12 100644 (file)
@@ -172,21 +172,21 @@ protected:
   int num_dirty;
 
   // state
-  version_t       version;
-  version_t       committing_version;
-  version_t       committed_version;
-  version_t       committed_version_equivalent;  // in case of, e.g., temporary file
-  version_t       projected_version; 
+  version_t version;
+  version_t committing_version;
+  version_t committed_version;
+  version_t committed_version_equivalent;  // in case of, e.g., temporary file
+  version_t projected_version; 
 
   // lock nesting, freeze
-  int        auth_pins;
-  int        nested_auth_pins;
-  int        request_pins;
+  int auth_pins;
+  int nested_auth_pins;
+  int request_pins;
 
 
   // cache control  (defined for authority; hints for replicas)
-  int              dir_rep;
-  set<int>         dir_rep_by;      // if dir_rep == REP_LIST
+  int      dir_rep;
+  set<int> dir_rep_by;      // if dir_rep == REP_LIST
 
   // popularity
   dirfrag_load_vec_t pop_me;
@@ -393,17 +393,16 @@ public:
   void auth_pin();
   void auth_unpin();
   void adjust_nested_auth_pins(int inc);
-  void on_freezeable();
 
   // -- freezing --
   void freeze_tree(Context *c);
   void freeze_tree_finish(Context *c);
   void unfreeze_tree();
-  void _freeze_tree(Context *c=0);
+  void _freeze_tree();
 
   void freeze_dir(Context *c);
   void freeze_dir_finish(Context *c);
-  void _freeze_dir(Context *c=0);
+  void _freeze_dir();
   void unfreeze_dir();
 
   bool is_freezing() { return is_freezing_tree() || is_freezing_dir(); }
@@ -416,9 +415,9 @@ public:
   bool is_frozen_tree_root() { return state & STATE_FROZENTREE; }
   bool is_frozen_dir() { return state & STATE_FROZENDIR; }
   
-  bool is_freezeable() {
+  bool is_freezeable(bool freezing=false) {
     // no nested auth pins.
-    if (auth_pins > 0 || nested_auth_pins > 0) 
+    if ((auth_pins-freezing) > 0 || nested_auth_pins > 0) 
       return false;
 
     // inode must not be frozen.
@@ -427,8 +426,8 @@ public:
 
     return true;
   }
-  bool is_freezeable_dir() {
-    if (auth_pins > 0) 
+  bool is_freezeable_dir(bool freezing=false) {
+    if ((auth_pins-freezing) > 0) 
       return false;
 
     // if not subtree root, inode must not be frozen (tree--frozen_dir is okay).
index 912823cf8632168bf4d966aebdb840a960b271ea..6cd1e69c512412ccc49b3fda4e56bfa077d4601b 100644 (file)
@@ -146,9 +146,10 @@ public:
   frag_t pick_dirfrag(const string &dn);
   bool has_dirfrags() { return !dirfrags.empty(); }
   CDir* get_dirfrag(frag_t fg) {
-    if (dirfrags.count(fg)) 
+    if (dirfrags.count(fg)) {
+      assert(dirfragtree.is_leaf(fg));
       return dirfrags[fg];
-    else
+    else
       return 0;
   }
   void get_dirfrags_under(frag_t fg, list<CDir*>& ls);
index 878577cce3a19381ac4419134a42c1ea2ad0c27f..9825e111851fe60f076131c983fe23c3daa86326 100644 (file)
@@ -5528,12 +5528,16 @@ void MDCache::adjust_dir_fragments(CInode *diri, frag_t basefrag, int bits,
   dout(10) << "adjust_dir_fragments " << basefrag << " " << bits 
           << " on " << *diri << endl;
 
+  // yuck.  we may have discovered the inode while it was being fragmented.
+  if (!diri->dirfragtree.is_leaf(basefrag))
+    diri->dirfragtree.force_to_leaf(basefrag);
+
+  CDir *base = diri->get_or_open_dirfrag(this, basefrag);
+
   // adjust fragtree
   diri->dirfragtree.split(basefrag, bits);
   dout(10) << " new fragtree is " << diri->dirfragtree << endl;
 
-  CDir *base = diri->get_or_open_dirfrag(this, basefrag);
-
   if (bits > 0) {
     if (base) {
       CDir *baseparent = base->get_parent_dir();
index 9f30de72d4c091d52c5537d11b7683205ae3d61e..a9cbf9f7b7c8e619ec2d6807e3cf4ada0117c746 100644 (file)
@@ -307,7 +307,7 @@ void Migrator::handle_mds_failure_or_stop(int who)
     CDir *dir = mds->mdcache->get_dirfrag(df);
 
     if (import_peer[df] == who) {
-      switch (import_state[df]) {
+      switch (q->second) {
       case IMPORT_DISCOVERING:
        dout(10) << "import state=discovering : clearing state" << endl;
        import_state.erase(df);
@@ -324,7 +324,7 @@ void Migrator::handle_mds_failure_or_stop(int who)
        break;
 
       case IMPORT_PREPPING:
-       if (import_state[df] == IMPORT_PREPPING) {
+       if (q->second == IMPORT_PREPPING) {
          dout(10) << "import state=prepping : unpinning base+bounds " << *dir << endl;
        }
        assert(dir);