]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: Check for LOCK_MIX_STALE along with LOCK_MIX
authorGreg Farnum <gregf@hq.newdream.net>
Sat, 16 Oct 2010 00:05:24 +0000 (17:05 -0700)
committerGreg Farnum <gregf@hq.newdream.net>
Fri, 22 Oct 2010 22:51:23 +0000 (15:51 -0700)
LOCK_MIX_STALE precludes writing to the protected data, but
in general cases it's an acceptable state whenever LOCK_MIX is.

Add checks for LOCK_MIX_STALE to asserts and if statements that
match those for LOCK_MIX.

src/mds/CInode.cc
src/mds/Locker.cc

index 19131b5e55d804d2223a9993501c27774458ed33..c360efb099f8e049cce2b22cc51158fbb76db6af 100644 (file)
@@ -2391,7 +2391,8 @@ void CInode::decode_import(bufferlist::iterator& p,
       // it is frozen (and in a SYNC or LOCK state).  FIXME.
 
       if (dir->is_auth() ||
-         filelock.get_state() == LOCK_MIX) {
+         filelock.get_state() == LOCK_MIX ||
+         filelock.get_state() == LOCK_MIX_STALE) {
        dout(10) << " skipped fragstat info for " << *dir << dendl;
        frag_info_t f;
        ::decode(f, q);
@@ -2402,7 +2403,8 @@ void CInode::decode_import(bufferlist::iterator& p,
        dout(10) << " took fragstat info for " << *dir << dendl;
       }
       if (dir->is_auth() ||
-         nestlock.get_state() == LOCK_MIX) {
+         nestlock.get_state() == LOCK_MIX ||
+         nestlock.get_state() == LOCK_MIX_STALE) {
        dout(10) << " skipped rstat info for " << *dir << dendl;
        nest_info_t n;
        ::decode(n, q);
index 037aece238253ca9927912e7fc08b7f5766f6fbd..91429351ac94169fd2ee99f843b6d78eca8f81e1 100644 (file)
@@ -2955,6 +2955,7 @@ bool Locker::simple_sync(SimpleLock *lock, bool *need_issue)
   if (old_state != LOCK_TSYN) {
 
     switch (lock->get_state()) {
+    case LOCK_MIX_STALE:
     case LOCK_MIX: lock->set_state(LOCK_MIX_SYNC); break;
     case LOCK_SCAN:
     case LOCK_LOCK: lock->set_state(LOCK_LOCK_SYNC); break;
@@ -2969,7 +2970,7 @@ bool Locker::simple_sync(SimpleLock *lock, bool *need_issue)
       gather++;
     
     if (lock->get_parent()->is_replicated() && 
-       old_state == LOCK_MIX) {
+       ((old_state == LOCK_MIX) || (old_state == LOCK_MIX_STALE))) {
       send_lock_message(lock, LOCK_AC_SYNC);
       lock->init_gather();
       gather++;
@@ -3081,6 +3082,7 @@ void Locker::simple_lock(SimpleLock *lock, bool *need_issue)
   case LOCK_SCAN: lock->set_state(LOCK_SCAN_LOCK); break;
   case LOCK_SYNC: lock->set_state(LOCK_SYNC_LOCK); break;
   case LOCK_EXCL: lock->set_state(LOCK_EXCL_LOCK); break;
+  case LOCK_MIX_STALE:
   case LOCK_MIX: lock->set_state(LOCK_MIX_LOCK); break;
   case LOCK_TSYN: lock->set_state(LOCK_TSYN_LOCK); break;
   default: assert(0);
@@ -3290,7 +3292,8 @@ void Locker::scatter_eval(ScatterLock *lock, bool *need_issue)
   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)
+       lock->get_state() != LOCK_MIX &&
+       lock->get_state() != LOCK_MIX_STALE)
       file_mixed(lock, need_issue);
       return;
   }
@@ -3385,7 +3388,8 @@ void Locker::scatter_nudge(ScatterLock *lock, Context *c, bool forcelockchange)
        dout(10) << "scatter_nudge auth, scatter/unscattering " << *lock << " on " << *p << dendl;
        switch (lock->get_type()) {
        case CEPH_LOCK_IFILE:
-         if (p->is_replicated() && lock->get_state() != LOCK_MIX)
+         if (p->is_replicated() && lock->get_state() != LOCK_MIX &&
+             lock->get_state() != LOCK_MIX_STALE)
            file_mixed((ScatterLock*)lock);
          else if (lock->get_state() != LOCK_LOCK)
            simple_lock((ScatterLock*)lock);
@@ -3395,7 +3399,8 @@ void Locker::scatter_nudge(ScatterLock *lock, Context *c, bool forcelockchange)
          
        case CEPH_LOCK_IDFT:
        case CEPH_LOCK_INEST:
-         if (p->is_replicated() && lock->get_state() != LOCK_MIX)
+         if (p->is_replicated() && lock->get_state() != LOCK_MIX &&
+             lock->get_state() != LOCK_MIX_STALE)
            file_mixed(lock);
          else if (lock->get_state() != LOCK_LOCK)
            simple_lock(lock);
@@ -3477,6 +3482,7 @@ void Locker::scatter_tempsync(ScatterLock *lock, bool *need_issue)
   switch (lock->get_state()) {
   case LOCK_SYNC: assert(0);   // this shouldn't happen
   case LOCK_LOCK: lock->set_state(LOCK_LOCK_TSYN); break;
+  case LOCK_MIX_STALE:
   case LOCK_MIX: lock->set_state(LOCK_MIX_TSYN); break;
   default: assert(0);
   }
@@ -3645,7 +3651,7 @@ void Locker::file_eval(ScatterLock *lock, bool *need_issue)
   }
 
   // * -> mixed?
-  else if (lock->get_state() != LOCK_MIX &&
+  else if (lock->get_state() != LOCK_MIX && lock->get_state() != LOCK_MIX_STALE &&
           //!lock->is_rdlocked() &&
           //!lock->is_waiter_for(SimpleLock::WAIT_WR) &&
           (lock->get_scatter_wanted() ||
@@ -3660,7 +3666,7 @@ void Locker::file_eval(ScatterLock *lock, bool *need_issue)
           !lock->is_wrlocked() &&   // drain wrlocks first!
           !in->filelock.is_waiter_for(SimpleLock::WAIT_WR) &&
           !(wanted & (CEPH_CAP_GWR|CEPH_CAP_GBUFFER)) &&
-          !(lock->get_state() == LOCK_MIX &&
+          !((in->get_state() == LOCK_MIX || in->get_state() == LOCK_MIX_STALE) &&
             in->is_dir() && in->has_subtree_root_dirfrag())  // if we are a delegation point, stay where we are
           //((wanted & CEPH_CAP_RD) || 
           //in->is_replicated() || 
@@ -3769,6 +3775,7 @@ void Locker::file_excl(ScatterLock *lock, bool *need_issue)
   
   switch (lock->get_state()) {
   case LOCK_SYNC: lock->set_state(LOCK_SYNC_EXCL); break;
+  case LOCK_MIX_STALE:
   case LOCK_MIX: lock->set_state(LOCK_MIX_EXCL); break;
   case LOCK_SCAN:
   case LOCK_LOCK: lock->set_state(LOCK_LOCK_EXCL); break;
@@ -3870,10 +3877,10 @@ void Locker::handle_file_lock(ScatterLock *lock, MLock *m)
     // -- replica --
   case LOCK_AC_SYNC:
     assert(lock->get_state() == LOCK_LOCK ||
-          lock->get_state() == LOCK_MIX ||
+          lock->get_state() == LOCK_MIX || lock->get_state() == LOCK_MIX_STALE ||
           lock->get_state() == LOCK_MIX_SYNC2);
     
-    if (lock->get_state() == LOCK_MIX) {
+    if (lock->get_state() == LOCK_MIX || lock->get_state() == LOCK_MIX_STALE) {
       lock->set_state(LOCK_MIX_SYNC);
       eval_gather(lock, true);
       break;
@@ -3893,6 +3900,7 @@ void Locker::handle_file_lock(ScatterLock *lock, MLock *m)
   case LOCK_AC_LOCK:
     switch (lock->get_state()) {
     case LOCK_SYNC: lock->set_state(LOCK_SYNC_LOCK); break;
+    case LOCK_MIX_STALE:
     case LOCK_MIX: lock->set_state(LOCK_MIX_LOCK); break;
     default: assert(0);
     }
@@ -3994,7 +4002,8 @@ void Locker::handle_file_lock(ScatterLock *lock, MLock *m)
        */
       dout(7) << "handle_file_lock got scatter request on " << *lock
              << " on " << *lock->get_parent() << dendl;
-      if (lock->get_state() != LOCK_MIX)  // i.e., the reqscatter didn't race with an actual mix/scatter
+      if (lock->get_state() != LOCK_MIX &&
+          lock->get_state() != LOCK_MIX_STALE)  // i.e., the reqscatter didn't race with an actual mix/scatter
        file_mixed(lock);
     } else {
       dout(7) << "handle_file_lock ignoring scatter request on " << *lock