]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: merge scatter and file lock message handlers
authorSage Weil <sage@newdream.net>
Thu, 12 Mar 2009 20:35:13 +0000 (13:35 -0700)
committerSage Weil <sage@newdream.net>
Thu, 12 Mar 2009 21:20:06 +0000 (14:20 -0700)
And fix some issues along the way.

src/mds/Locker.cc
src/mds/locks.c

index 6c6b0fa647b3f36de7ae2c76178bf86ccb724cae..92052b0e46d42d7864e91736a7dee8e59d6c04af 100644 (file)
@@ -482,10 +482,12 @@ void Locker::eval_gather(SimpleLock *lock)
          send_lock_message(lock, LOCK_AC_MIX, softdata);
        }
        break;
-       
+
+       // to sync
       case LOCK_EXCL_SYNC:
       case LOCK_LOCK_SYNC:
-       { // bcast data to replicas
+      case LOCK_MIX_SYNC:
+       if (in->is_replicated()) {
          bufferlist softdata;
          lock->encode_locked_state(softdata);
          send_lock_message(lock, LOCK_AC_SYNC, softdata);
@@ -673,10 +675,7 @@ bool Locker::wrlock_start(SimpleLock *lock, MDRequest *mut, bool nowait)
 
     if (in->is_auth()) {
       if (want_scatter) {
-       if (lock->sm == &sm_filelock)
-         file_mixed((ScatterLock*)lock);
-       else 
-         scatter_scatter((ScatterLock*)lock, nowait);
+       file_mixed((ScatterLock*)lock);
       } else 
        simple_lock(lock);
 
@@ -1960,15 +1959,15 @@ void Locker::handle_lock(MLock *m)
     handle_simple_lock(lock, m);
     break;
     
+  case CEPH_LOCK_IDFT:
+  case CEPH_LOCK_INEST:
+    //handle_scatter_lock((ScatterLock*)lock, m);
+    //break;
+
   case CEPH_LOCK_IFILE:
     handle_file_lock((ScatterLock*)lock, m);
     break;
     
-  case CEPH_LOCK_IDFT:
-  case CEPH_LOCK_INEST:
-    handle_scatter_lock((ScatterLock*)lock, m);
-    break;
-
   default:
     dout(7) << "handle_lock got otype " << m->get_lock_type() << dendl;
     assert(0);
@@ -2460,11 +2459,12 @@ void Locker::scatter_eval(ScatterLock *lock)
 
   if (lock->get_parent()->is_frozen()) return;
   
-  if (lock->get_type() == CEPH_LOCK_INEST &&
-      !lock->is_rdlocked() &&
-      lock->get_state() != LOCK_MIX) {
-    scatter_scatter(lock);
-    return;
+  if (lock->get_type() == CEPH_LOCK_INEST) {
+    // in general, we want to keep INEST scattered at all times.
+    if (!lock->is_rdlocked() &&
+       lock->get_state() != LOCK_MIX)
+      file_mixed(lock);
+      return;
   }
 
   CInode *in = (CInode*)lock->get_parent();
@@ -2545,7 +2545,7 @@ void Locker::scatter_nudge(ScatterLock *lock, Context *c)
       case CEPH_LOCK_IDFT:
       case CEPH_LOCK_INEST:
        if (p->is_replicated() && lock->get_state() != LOCK_MIX)
-         scatter_scatter(lock);
+         file_mixed(lock);
        else // if (lock->get_state() != LOCK_LOCK)
          simple_lock(lock);
        //else
@@ -2598,73 +2598,6 @@ void Locker::scatter_tick()
 }
 
 
-
-bool Locker::scatter_scatter_fastpath(ScatterLock *lock)
-{
-  assert(lock->get_parent()->is_auth());
-  assert(lock->is_stable());
-
-  if (lock->get_state() == LOCK_MIX)
-    return true;
-  if (!lock->is_rdlocked() &&
-      !lock->is_xlocked() &&
-      !lock->get_num_client_lease() &&
-      (!lock->get_parent()->is_replicated() ||  // if sync
-       lock->get_state() == LOCK_LOCK ||
-       lock->get_state() == LOCK_TSYN)) {
-    dout(10) << "scatter_scatter_fastpath YES " << *lock
-            << " on " << *lock->get_parent() << dendl;
-    // do scatter
-    lock->set_last_scatter(g_clock.now());
-
-    if (lock->get_parent()->is_replicated()) {
-      // encode and bcast
-      bufferlist data;
-      lock->encode_locked_state(data);
-      send_lock_message(lock, LOCK_AC_MIX, data);
-    } 
-    
-    ((CInode *)lock->get_parent())->try_drop_loner();
-
-    lock->set_state(LOCK_MIX);
-    lock->finish_waiters(ScatterLock::WAIT_WR|ScatterLock::WAIT_STABLE);
-    return true;
-  }
-  dout(20) << "scatter_scatter_fastpath NO " << *lock
-          << " on " << *lock->get_parent() << dendl;
-  return false;
-}
-
-void Locker::scatter_scatter(ScatterLock *lock, bool nowait)
-{
-  dout(10) << "scatter_scatter " << *lock
-          << " on " << *lock->get_parent() << dendl;
-  assert(lock->get_parent()->is_auth());
-  assert(lock->is_stable());
-  
-  if (scatter_scatter_fastpath(lock) || nowait)
-    return;
-
-  if (lock->is_xlocked())
-    return;  // do nothing.
-
-  switch (lock->get_state()) {
-  case LOCK_SYNC: lock->set_state(LOCK_SYNC_MIX); break;
-  case LOCK_TSYN: lock->set_state(LOCK_TSYN_MIX); break;
-  default: assert(0);
-  }
-
-  lock->get_parent()->auth_pin(lock);
-
-  if (lock->get_parent()->is_replicated()) {
-    send_lock_message(lock, LOCK_AC_LOCK);
-    lock->init_gather();
-  }
-  if (lock->get_num_client_lease())
-    revoke_client_leases(lock);
-}
-
-
 void Locker::scatter_tempsync(ScatterLock *lock)
 {
   dout(10) << "scatter_tempsync " << *lock
@@ -2715,145 +2648,6 @@ void Locker::scatter_tempsync(ScatterLock *lock)
 
 
 
-void Locker::handle_scatter_lock(ScatterLock *lock, MLock *m)
-{
-  int from = m->get_asker();
-  dout(10) << "handle_scatter_lock " << *m << " on " << *lock << " on " << *lock->get_parent() << dendl;
-  
-  if (mds->is_rejoin()) {
-    if (lock->get_parent()->is_rejoining()) {
-      dout(7) << "handle_scatter_lock still rejoining " << *lock->get_parent()
-             << ", dropping " << *m << dendl;
-      delete m;
-      return;
-    }
-  }
-
-  switch (m->get_action()) {
-    // -- replica --
-  case LOCK_AC_SYNC:
-    assert(lock->get_state() == LOCK_LOCK);
-    lock->set_state(LOCK_SYNC);
-    lock->decode_locked_state(m->get_data());
-    lock->clear_updated();
-    lock->finish_waiters(ScatterLock::WAIT_RD|ScatterLock::WAIT_STABLE);
-    break;
-
-  case LOCK_AC_LOCK:
-    assert(lock->get_state() == LOCK_MIX ||
-          lock->get_state() == LOCK_SYNC);
-
-    // wait for wrlocks to close?
-    if (lock->is_wrlocked()) {
-      assert(lock->get_state() == LOCK_MIX);
-      dout(7) << "handle_scatter_lock has wrlocks, waiting on " << *lock
-             << " on " << *lock->get_parent() << dendl;
-      lock->set_state(LOCK_MIX_LOCK);
-    } else if (lock->is_rdlocked() ||
-              lock->get_num_client_lease()) {
-      assert(lock->get_state() == LOCK_SYNC);
-      dout(7) << "handle_scatter_lock has rdlocks|leases, waiting on " << *lock
-             << " on " << *lock->get_parent() << dendl;
-      revoke_client_leases(lock);
-      lock->set_state(LOCK_SYNC_LOCK);
-    } else {
-      dout(7) << "handle_scatter_lock has no rd|wrlocks|leases, sending lockack for " << *lock
-             << " on " << *lock->get_parent() << dendl;
-      
-      // encode and reply
-      bufferlist data;
-      lock->encode_locked_state(data);
-      mds->send_message_mds(new MLock(lock, LOCK_AC_LOCKACK, mds->get_nodeid(), data), from);
-      lock->set_state(LOCK_LOCK);
-    }
-    break;
-
-  case LOCK_AC_MIX:
-    assert(lock->get_state() == LOCK_LOCK);
-    lock->decode_locked_state(m->get_data());
-    lock->clear_updated();
-    lock->set_state(LOCK_MIX);
-    lock->finish_waiters(ScatterLock::WAIT_WR|ScatterLock::WAIT_STABLE);
-    break;
-
-    // -- for auth --
-  case LOCK_AC_LOCKACK:
-    assert(lock->get_state() == LOCK_SYNC_LOCK ||
-          lock->get_state() == LOCK_MIX_LOCK ||
-          lock->get_state() == LOCK_SYNC_MIX ||
-          lock->get_state() == LOCK_MIX_TSYN);
-    assert(lock->is_gathering(from));
-    lock->remove_gather(from);
-    lock->decode_locked_state(m->get_data());
-    
-    if (lock->is_gathering()) {
-      dout(7) << "handle_scatter_lock " << *lock << " on " << *lock->get_parent()
-             << " from " << from << ", still gathering " << lock->get_gather_set()
-             << dendl;
-    } else {
-      dout(7) << "handle_scatter_lock " << *lock << " on " << *lock->get_parent()
-             << " from " << from << ", last one" 
-             << dendl;
-      eval_gather(lock);
-    }
-    break;
-
-  case LOCK_AC_REQSCATTER:
-    if (lock->is_stable()) {
-      /* NOTE: we can do this _even_ if !can_auth_pin (i.e. freezing)
-       *  because the replica should be holding an auth_pin if they're
-       *  doing this (and thus, we are freezing, not frozen, and indefinite
-       *  starvation isn't an issue).
-       */
-      dout(7) << "handle_scatter_lock got scatter request on " << *lock
-             << " on " << *lock->get_parent() << dendl;
-      scatter_scatter(lock);
-    } else {
-      dout(7) << "handle_scatter_lock ignoring scatter request on " << *lock
-             << " on " << *lock->get_parent() << dendl;
-    }
-    break;
-
-    /*
-  case LOCK_AC_REQUNMIX:
-    if (!lock->is_stable()) {
-      dout(7) << "handle_scatter_lock ignoring now-unnecessary unscatter request on " << *lock
-             << " on " << *lock->get_parent() << dendl;
-    } else if (lock->get_parent()->can_auth_pin()) {
-      dout(7) << "handle_scatter_lock got unscatter request on " << *lock
-             << " on " << *lock->get_parent() << dendl;
-      scatter_lock(lock);
-    } else {
-      dout(7) << "handle_scatter_lock DROPPING unscatter request on " << *lock
-             << " on " << *lock->get_parent() << dendl;
-      // FIXME: if we can't auth_pin here, this request is effectively lost... 
-    }
-    break;
-    */
-
-  case LOCK_AC_NUDGE:
-    if (lock->get_parent()->is_auth()) {
-      dout(7) << "handle_scatter_lock trying nudge on " << *lock
-             << " on " << *lock->get_parent() << dendl;
-      scatter_nudge(lock, 0);
-    } else {
-      dout(7) << "handle_scatter_lock IGNORING nudge on non-auth " << *lock
-             << " on " << *lock->get_parent() << dendl;
-    }    
-    break;
-
- default: 
-   assert(0);
-  }
-
-  delete m;
-}
-
-
-
-
-
-
 // ==========================================================================
 // local lock
 
@@ -3085,6 +2879,7 @@ void Locker::file_mixed(ScatterLock *lock)
     switch (lock->get_state()) {
     case LOCK_SYNC: lock->set_state(LOCK_SYNC_MIX); break;
     case LOCK_EXCL: lock->set_state(LOCK_EXCL_MIX); break;
+    case LOCK_TSYN: lock->set_state(LOCK_TSYN_MIX); break;
     default: assert(0);
     }
 
@@ -3100,12 +2895,14 @@ void Locker::file_mixed(ScatterLock *lock)
       revoke_client_leases(lock);
       gather++;
     }
-    int loner_issued, other_issued;
-    in->get_caps_issued(&loner_issued, &other_issued, CEPH_CAP_SFILE);
-    if ((loner_issued & ~lock->gcaps_allowed(true)) ||
-       (other_issued & ~lock->gcaps_allowed(false))) {
-      issue_caps(in);
-      gather++;
+    if (lock->get_cap_shift()) {
+      int loner_issued, other_issued;
+      in->get_caps_issued(&loner_issued, &other_issued, lock->get_cap_shift());
+      if ((loner_issued & ~lock->gcaps_allowed(true)) ||
+         (other_issued & ~lock->gcaps_allowed(false))) {
+       issue_caps(in);
+       gather++;
+      }
     }
     if (in->state_test(CInode::STATE_NEEDSRECOVER)) {
       mds->mdcache->queue_file_recover(in);
@@ -3118,7 +2915,8 @@ void Locker::file_mixed(ScatterLock *lock)
     else {
       in->try_drop_loner();
       lock->set_state(LOCK_MIX);
-      issue_caps(in);
+      if (lock->get_cap_shift())
+       issue_caps(in);
     }
   }
 }
@@ -3192,11 +2990,12 @@ void Locker::handle_file_lock(ScatterLock *lock, MLock *m)
     }
   }
 
-
   dout(7) << "handle_file_lock a=" << get_lock_action_name(m->get_action())
          << " on " << *lock
          << " from mds" << from << " " 
          << *in << dendl;
+
+  bool caps = lock->get_cap_shift();
   
   switch (m->get_action()) {
     // -- replica --
@@ -3238,9 +3037,10 @@ void Locker::handle_file_lock(ScatterLock *lock, MLock *m)
     
     // call back caps?
     int loner_issued, other_issued;
-    in->get_caps_issued(&loner_issued, &other_issued, CEPH_CAP_SFILE);
-    if ((loner_issued & ~lock->gcaps_allowed(true)) ||
-       (other_issued & ~lock->gcaps_allowed(false))) {
+    if (caps)
+      in->get_caps_issued(&loner_issued, &other_issued, CEPH_CAP_SFILE);
+    if (caps && ((loner_issued & ~lock->gcaps_allowed(true)) ||
+                (other_issued & ~lock->gcaps_allowed(false)))) {
       dout(7) << "handle_file_lock client readers, gathering caps on " << *in << dendl;
       issue_caps(in);
       break;
@@ -3290,7 +3090,8 @@ void Locker::handle_file_lock(ScatterLock *lock, MLock *m)
       // no ack needed.
     }
 
-    issue_caps(in);
+    if (caps)
+      issue_caps(in);
     
     // waiters
     lock->finish_waiters(SimpleLock::WAIT_WR|SimpleLock::WAIT_STABLE);
@@ -3304,37 +3105,39 @@ void Locker::handle_file_lock(ScatterLock *lock, MLock *m)
     assert(lock->get_state() == LOCK_SYNC_LOCK ||
            lock->get_state() == LOCK_MIX_LOCK ||
            lock->get_state() == LOCK_MIX_EXCL ||
-           lock->get_state() == LOCK_SYNC_EXCL);
+           lock->get_state() == LOCK_SYNC_EXCL ||
+           lock->get_state() == LOCK_SYNC_MIX ||
+          lock->get_state() == LOCK_MIX_TSYN);
     assert(lock->is_gathering(from));
     lock->remove_gather(from);
     
     if (lock->get_state() == LOCK_MIX_LOCK ||
-       lock->get_state() == LOCK_MIX_EXCL)
+       lock->get_state() == LOCK_MIX_EXCL ||
+       lock->get_state() == LOCK_MIX_TSYN)
       lock->decode_locked_state(m->get_data());
 
     if (lock->is_gathering()) {
-      dout(7) << "handle_lock_inode_file " << *in << " from " << from
+      dout(7) << "handle_file_lock " << *in << " from " << from
              << ", still gathering " << lock->get_gather_set() << dendl;
     } else {
-      dout(7) << "handle_lock_inode_file " << *in << " from " << from
+      dout(7) << "handle_file_lock " << *in << " from " << from
              << ", last one" << dendl;
       eval_gather(lock);
     }
     break;
     
   case LOCK_AC_SYNCACK:
-    assert(lock->get_state() == LOCK_MIX_SYNC ||
-          lock->get_state() == LOCK_MIX_SYNC2);
+    assert(lock->get_state() == LOCK_MIX_SYNC);
     assert(lock->is_gathering(from));
     lock->remove_gather(from);
     
     lock->decode_locked_state(m->get_data());
 
     if (lock->is_gathering()) {
-      dout(7) << "handle_lock_inode_file " << *in << " from " << from
+      dout(7) << "handle_file_lock " << *in << " from " << from
              << ", still gathering " << lock->get_gather_set() << dendl;
     } else {
-      dout(7) << "handle_lock_inode_file " << *in << " from " << from
+      dout(7) << "handle_file_lock " << *in << " from " << from
              << ", last one" << dendl;
       eval_gather(lock);
     }
@@ -3346,10 +3149,10 @@ void Locker::handle_file_lock(ScatterLock *lock, MLock *m)
     lock->remove_gather(from);
     
     if (lock->is_gathering()) {
-      dout(7) << "handle_lock_inode_file " << *in << " from " << from
+      dout(7) << "handle_file_lock " << *in << " from " << from
              << ", still gathering " << lock->get_gather_set() << dendl;
     } else {
-      dout(7) << "handle_lock_inode_file " << *in << " from " << from
+      dout(7) << "handle_file_lock " << *in << " from " << from
              << ", last one" << dendl;
       eval_gather(lock);
     }
index 929e7bce08dd5439ff6ad1c94e4868361a3191af..cc7789ecd6b3866db2b1fd759848e6d60a60a8bc 100644 (file)
@@ -65,6 +65,7 @@ struct sm_state_t scatterlock[30] = {
     [LOCK_MIX]       = { 0,         false, LOCK_MIX,  0,    0,   FW,  ANY, 0,   0,   0,0,0 },
     [LOCK_TSYN_MIX]  = { LOCK_MIX,  false, LOCK_LOCK, 0,    0,   0,   0,   0,   0,   0,0,0 },
     [LOCK_SYNC_MIX]  = { LOCK_MIX,  false, LOCK_LOCK, 0,    0,   0,   0,   0,   0,   0,0,0 },
+    [LOCK_SYNC_MIX2] = { LOCK_MIX,  false, 0,         0,    0,   0,   0,   0,   0,   0,0,0 },
 };
 
 struct sm_t sm_scatterlock = {