]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: clear replica lock dirty flag when state is flushed back to primary
authorSage Weil <sage@newdream.net>
Thu, 12 Mar 2009 21:48:42 +0000 (14:48 -0700)
committerSage Weil <sage@newdream.net>
Thu, 12 Mar 2009 23:11:31 +0000 (16:11 -0700)
The dirty -> flush -> clean bit is probably overkill, given the
locking rules, but it's very explicit.

src/TODO
src/mds/CInode.cc
src/mds/Locker.cc
src/mds/MDCache.cc
src/mds/MDCache.h
src/mds/ScatterLock.h
src/mds/Server.cc
src/mds/journal.cc

index 9e81c1c9b2d2b278e76022ce4974e08d65251156..f5580f29a159da2004e23d6f806aaf52b5f7b462 100644 (file)
--- a/src/TODO
+++ b/src/TODO
@@ -93,6 +93,7 @@ userspace client
 - fix readdir vs fragment race by keeping a separate frag pos, and ignoring dentries below it
 
 mds
+- on replay, but dirty scatter replicas on lists so that they get flushed?  or does rejoin handle that?
 - take some care with replayed client requests vs new requests
 - linkage vs cdentry replicas and remote rename....
 - move root inode into stray dir
index b239990ac4ea6d447cc527cb64ba19ea6a8c5bef..7ca4305dc43f2b12d23be9aa67a6ce622e57d616 100644 (file)
@@ -766,7 +766,7 @@ void CInode::decode_lock_state(int type, bufferlist& bl)
          if (!dirfragtree.is_leaf(*p)) {
            dout(10) << " forcing frag " << *p << " to leaf (split|merge)" << dendl;
            dirfragtree.force_to_leaf(*p);
-           dirfragtreelock.set_updated();
+           dirfragtreelock.mark_dirty();  // ok bc we're auth and caller will handle
          }
       } else {
        // replica.  take the new tree, BUT make sure any open
@@ -829,7 +829,7 @@ void CInode::decode_lock_state(int type, bufferlist& bl)
          dir->first = fgfirst;
          if (!(fragstat == accounted_fragstat)) {
            dout(10) << fg << " setting filelock updated flag" << dendl;
-           filelock.set_updated();
+           filelock.mark_dirty();  // ok bc we're auth and caller will handle
          }
        } else {
          if (dir && dir->is_auth()) {
@@ -886,7 +886,7 @@ void CInode::decode_lock_state(int type, bufferlist& bl)
          dir->dirty_old_rstat.swap(dirty_old_rstat);
          if (!(rstat == accounted_rstat) || dir->dirty_old_rstat.size()) {
            dout(10) << fg << " setting nestlock updated flag" << dendl;
-           nestlock.set_updated();
+           nestlock.mark_dirty();  // ok bc we're auth and caller will handle
          }
        } else {
          if (dir && dir->is_auth()) {
index 202337920d2100de528babba79c79b68d5f3d33d..1119704153ce139447345322d17a2d93afd81ce8 100644 (file)
@@ -441,10 +441,13 @@ void Locker::eval_gather(SimpleLock *lock, bool first)
            lock->encode_locked_state(reply->get_data());
            mds->send_message_mds(reply, auth);
            next = LOCK_MIX_SYNC2;
+           ((ScatterLock *)lock)->start_flush();
          }
          break;
 
        case LOCK_MIX_SYNC2:
+         ((ScatterLock *)lock)->finish_flush();
+
        case LOCK_SYNC_MIX2:
          // do nothing, we already acked
          break;
@@ -2410,7 +2413,7 @@ void Locker::scatter_writebehind(ScatterLock *lock)
   // hack:
   if (in->is_base()) {
     dout(10) << "scatter_writebehind just clearing updated flag for base inode " << *in << dendl;
-    lock->clear_updated();
+    lock->clear_dirty();
     if (!lock->is_stable())
       eval_gather(lock);
     return;
@@ -2431,7 +2434,7 @@ void Locker::scatter_writebehind(ScatterLock *lock)
   pi->version = in->pre_dirty();
 
   lock->get_parent()->finish_scatter_gather_update(lock->get_type());
-  lock->clear_updated();
+  lock->start_flush();
 
   EUpdate *le = new EUpdate(mds->mdlog, "scatter_writebehind");
   mdcache->predirty_journal_parents(mut, &le->metablob, in, 0, PREDIRTY_PRIMARY, false);
@@ -2448,6 +2451,8 @@ void Locker::scatter_writebehind_finish(ScatterLock *lock, Mutation *mut)
   dout(10) << "scatter_writebehind_finish on " << *lock << " on " << *in << dendl;
   in->pop_and_dirty_projected_inode(mut->ls);
 
+  lock->finish_flush();
+
   mut->apply();
   drop_locks(mut);
   mut->cleanup();
@@ -2491,7 +2496,7 @@ void Locker::scatter_eval(ScatterLock *lock)
  */
 void Locker::mark_updated_scatterlock(ScatterLock *lock)
 {
-  lock->set_updated();
+  lock->mark_dirty();
   if (lock->xlistitem_updated.is_on_xlist()) {
     dout(10) << "mark_updated_scatterlock " << *lock
             << " -- already on list since " << lock->update_stamp << dendl;
index ed85fd9d06943e5fc21c58d1b80c745227bfe528..2e7a4321a4ac99a20ce21cb1da2da1b38fba196b 100644 (file)
@@ -2367,9 +2367,9 @@ void MDCache::recalc_auth_bits()
              dnl->get_inode()->mark_clean();
            // avoid touching scatterlocks for our subtree roots!
            if (subtree_inodes.count(dnl->get_inode()) == 0) {
-             dnl->get_inode()->filelock.clear_updated();
-             dnl->get_inode()->nestlock.clear_updated();
-             dnl->get_inode()->dirfragtreelock.clear_updated();
+             dnl->get_inode()->filelock.clear_dirty();
+             dnl->get_inode()->nestlock.clear_dirty();
+             dnl->get_inode()->dirfragtreelock.clear_dirty();
            }
          }
 
index fccc2e75e4e94775202420edec97126d8699ef6e..a4a855a016a0cb8cd88a4bc8a7e6c00a47fd29e9 100644 (file)
@@ -215,7 +215,7 @@ struct Mutation {
     for (list<ScatterLock*>::iterator p = updated_locks.begin();
         p != updated_locks.end();
         p++)
-      (*p)->set_updated();
+      (*p)->mark_dirty();
   }
 
   void cleanup() {
index 6c7089953711776a158a331ec1748e277c5ed995..fa07b3f97310f6f571b943ad75e9a8a13b6e53e4 100644 (file)
@@ -19,7 +19,7 @@
 #include "SimpleLock.h"
 
 class ScatterLock : public SimpleLock {
-  bool updated;
+  bool dirty, flushing;
   utime_t last_scatter;
 
 public:
@@ -28,26 +28,34 @@ public:
 
   ScatterLock(MDSCacheObject *o, int t, int ws) : 
     SimpleLock(o, t, ws),
-    updated(false),
+    dirty(false), flushing(false),
     xlistitem_updated(this) {}
   ~ScatterLock() {
     xlistitem_updated.remove_myself();   // FIXME this should happen sooner, i think...
   }
 
-  void set_updated() { 
-    if (!updated) {
-      parent->get(MDSCacheObject::PIN_DIRTYSCATTERED);
-      updated = true;
+  void mark_dirty() { 
+    if (!dirty) {
+      if (!flushing) 
+       parent->get(MDSCacheObject::PIN_DIRTYSCATTERED);
+      dirty = true;
     }
   }
-  void clear_updated() { 
-    if (updated) {
+  void start_flush() {
+    flushing |= dirty;
+    dirty = false;
+  }
+  void finish_flush() {
+    flushing = false;
+    if (!dirty) {
       parent->put(MDSCacheObject::PIN_DIRTYSCATTERED);
-      updated = false; 
       parent->clear_dirty_scattered(type);
     }
   }
-  bool is_updated() { return updated; }
+  void clear_dirty() {
+    start_flush();
+    finish_flush();
+  }
   
   void set_last_scatter(utime_t t) { last_scatter = t; }
   utime_t get_last_scatter() { return last_scatter; }
@@ -55,8 +63,10 @@ public:
   void print(ostream& out) {
     out << "(";
     _print(out);
-    if (updated)
-      out << " updated";
+    if (dirty)
+      out << " dirty";
+    if (flushing)
+      out << " flushing";
     out << ")";
   }
 };
index c7953c7f1bdb5a79d6e5ec46386a82c0d38e0d67..556c0f07776ece74cc719ea7a884a71ea2031170 100644 (file)
@@ -3896,8 +3896,8 @@ version_t Server::_rename_prepare_import(MDRequest *mdr, CDentry *srcdn, bufferl
                                         srcdn->authority().first,
                                         mdr->ls,
                                         mdr->more()->cap_imports, updated_scatterlocks);
-  srcdnl->get_inode()->filelock.clear_updated();  
-  srcdnl->get_inode()->nestlock.clear_updated();  
+  srcdnl->get_inode()->filelock.clear_dirty();  
+  srcdnl->get_inode()->nestlock.clear_dirty();  
 
   // hack: force back to !auth and clean, temporarily
   srcdnl->get_inode()->state_clear(CInode::STATE_AUTH);
index 8cde8cb94c0c9d1fd9bfd663843876361e967c85..c2f4844e9ec72fe1c62e5e2d61e05e1315b1b0e5 100644 (file)
@@ -360,7 +360,8 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg)
 
     if (lump.is_dirty()) {
       dir->_mark_dirty(logseg);
-      dir->get_inode()->filelock.set_updated();
+      dir->get_inode()->filelock.mark_dirty();
+      dir->get_inode()->nestlock.mark_dirty();
     }
     if (lump.is_new())
       dir->mark_new(logseg);