]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: preserve stale state on import; some cleanup
authorSage Weil <sage@newdream.net>
Sat, 6 Nov 2010 04:52:28 +0000 (21:52 -0700)
committerSage Weil <sage@newdream.net>
Sat, 6 Nov 2010 04:52:28 +0000 (21:52 -0700)
Our new invariant is that MIX_STALE always implies is_stale().  And on
import, if is_stale(), MIX becomes MIX_STALE.  This ensures that a replica
that we put into MIX_STALE doesn't turn back into MIX if we import it
and take the auth's state in CInode::decode_import().

Signed-off-by: Sage Weil <sage@newdream.net>
src/mds/CDir.cc
src/mds/CInode.cc
src/mds/Locker.cc
src/mds/ScatterLock.h

index b90e662d28c4c697cb317b756503e0292536fc73..d6354691f399b42774dbc00d1affafe6b30f6c32 100644 (file)
@@ -1194,9 +1194,9 @@ void CDir::_fetched(bufferlist &bl, const string& want_dn)
     projected_version = committing_version = committed_version = got_fnode.version;
 
     if (fnode.rstat.version < inode->inode.rstat.version)
-      inode->nestlock.set_stale();
+      inode->nestlock.set_and_apply_stale();
     if (fnode.fragstat.version < inode->inode.dirstat.version)
-      inode->filelock.set_stale();
+      inode->filelock.set_and_apply_stale();
   }
 
   // purge stale snaps?
@@ -1876,19 +1876,13 @@ void CDir::decode_import(bufferlist::iterator& blp, utime_t now)
   inode_t *pi = inode->get_projected_inode();
   if (fnode.fragstat.version != pi->dirstat.version) {
     dout(10) << " got stale fragstat " << fnode.fragstat << " vs inode " << pi->dirstat << dendl;
-    if (inode->filelock.get_state() == LOCK_MIX)
-      inode->filelock.set_state(LOCK_MIX_STALE);
-    else if (inode->filelock.get_state() != LOCK_MIX_STALE)
-      inode->filelock.set_stale();
+    inode->filelock.set_and_apply_stale();
   }
 
   // stale rstat?
   if (fnode.rstat.version != pi->rstat.version) {
     dout(10) << " got stale rstat " << fnode.rstat << " vs inode " << pi->rstat << dendl;
-    if (inode->nestlock.get_state() == LOCK_MIX)
-      inode->nestlock.set_state(LOCK_MIX_STALE);
-    else if (inode->nestlock.get_state() != LOCK_MIX_STALE)
-      inode->nestlock.set_stale();
+    inode->nestlock.set_and_apply_stale();
   }
 }
 
index 800919cec49e6634ae1b8ce0052e68634c7a0062..595dab8b2381c4c6ead96bd2fb86ea125f87d36e 100644 (file)
@@ -2373,9 +2373,11 @@ void CInode::_decode_locks_full(bufferlist::iterator& p)
   ::decode(linklock, p);
   ::decode(dirfragtreelock, p);
   ::decode(filelock, p);
+  filelock.apply_stale();
   ::decode(xattrlock, p);
   ::decode(snaplock, p);
   ::decode(nestlock, p);
+  nestlock.apply_stale();
   ::decode(flocklock, p);
   ::decode(policylock, p);
 }
index 7f8e2344921158fed318a959e633906b37d1b609..b97af0c4c0a3acca588e46ee829f8252eb4e22fc 100644 (file)
@@ -3965,12 +3965,11 @@ void Locker::handle_file_lock(ScatterLock *lock, MLock *m)
     
     // ok
     lock->decode_locked_state(m->get_data());
-    if (!lock->is_stale())
-      lock->set_state(LOCK_MIX);
-    else {
+    if (!lock->is_stale()) {
       dout(15) << "setting state to LOCK_MIX_STALE instead of LOCK_MIX" << dendl;
       lock->set_state(LOCK_MIX_STALE);
-    }
+    } else
+      lock->set_state(LOCK_MIX);
 
     ((ScatterLock *)lock)->finish_flush();
 
index 085ce400185a1ccd667f2884307ff1b8ee3c01f6..d9ffada083f5c30c67b2e7e7166646cc6b1a0af8 100644 (file)
@@ -141,21 +141,39 @@ public:
     start_flush();
     finish_flush();
   }
-  
+
+  /*
+   * "stale" means that at least one of our dirfrags has stale
+   * accounted_* scatter metadata on this inode.  that means that any
+   * transition to MIX needs to implicitly go to MIX_STALE.  also,
+   * MIX_STALE implies is_stale().
+   */  
   bool is_stale() const {
-    return have_more() && _more->stale;
+    if (have_more() && _more->stale)
+      return true;
+    assert(state != LOCK_MIX_STALE);   // invariant: LOCK_MIX_STALE => is_stale()
+    return false;
   }
-
   void set_stale() {
     more()->stale = true;
   }
-
   void clear_stale() {
     if (is_stale()) {
       _more->stale = false;
       try_clear_more();
     }
   }
+  void apply_stale() {
+    if (state == LOCK_MIX_STALE)
+      set_stale();
+    else if (is_stale() && state == LOCK_MIX)
+      state = LOCK_MIX_STALE;
+  }
+  void set_and_apply_stale() {
+    set_stale();
+    if (state == LOCK_MIX)
+      state = LOCK_MIX_STALE;
+  }
 
   void set_last_scatter(utime_t t) { more()->last_scatter = t; }
   utime_t get_last_scatter() {