]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: trim log segment after finishing uncommitted fragments
authorYan, Zheng <zheng.z.yan@intel.com>
Fri, 4 Oct 2013 12:56:58 +0000 (20:56 +0800)
committerYan, Zheng <zheng.z.yan@intel.com>
Sat, 5 Oct 2013 03:31:11 +0000 (11:31 +0800)
Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
src/mds/LogSegment.h
src/mds/MDCache.cc
src/mds/MDCache.h
src/mds/journal.cc

index 723267da116860c30d0d21325dc418b39438de6e..624c3bc2395e773a4a29506135597f2774fe26a6 100644 (file)
@@ -56,6 +56,7 @@ class LogSegment {
 
   map<int, hash_set<version_t> > pending_commit_tids;  // mdstable
   set<metareqid_t> uncommitted_masters;
+  set<dirfrag_t> uncommitted_fragments;
 
   // client request ids
   map<int, tid_t> last_client_tids;
index 9f97f31fcbf14594884b23d8e8e2a65476c06042..bde5735ea899715c9478d6f5bbc9d42f8edabb0e 100644 (file)
@@ -11191,7 +11191,7 @@ void MDCache::dispatch_fragment_dir(MDRequest *mdr)
   mut->add_updated_lock(&diri->nestlock);
   */
 
-  add_uncommitted_fragment(dirfrag_t(diri->ino(), info.basefrag), info.bits, le->orig_frags);
+  add_uncommitted_fragment(dirfrag_t(diri->ino(), info.basefrag), info.bits, le->orig_frags, mdr->ls);
   mds->mdlog->submit_entry(le, new C_MDC_FragmentPrep(this, mdr));
   mds->mdlog->flush();
 }
@@ -11379,13 +11379,15 @@ void MDCache::handle_fragment_notify(MMDSFragmentNotify *notify)
 }
 
 void MDCache::add_uncommitted_fragment(dirfrag_t basedirfrag, int bits, list<frag_t>& old_frags,
-                                      bufferlist *rollback)
+                                      LogSegment *ls, bufferlist *rollback)
 {
   dout(10) << "add_uncommitted_fragment: base dirfrag " << basedirfrag << " bits " << bits << dendl;
   assert(!uncommitted_fragments.count(basedirfrag));
   ufragment& uf = uncommitted_fragments[basedirfrag];
   uf.old_frags = old_frags;
   uf.bits = bits;
+  uf.ls = ls;
+  ls->uncommitted_fragments.insert(basedirfrag);
   if (rollback)
     uf.rollback.swap(*rollback);
 }
@@ -11399,6 +11401,8 @@ void MDCache::finish_uncommitted_fragment(dirfrag_t basedirfrag, int op)
     if (op != EFragment::OP_FINISH && !uf.old_frags.empty()) {
       uf.committed = true;
     } else {
+      uf.ls->uncommitted_fragments.erase(basedirfrag);
+      mds->queue_waiters(uf.waiters);
       uncommitted_fragments.erase(basedirfrag);
     }
   }
@@ -11414,6 +11418,7 @@ void MDCache::rollback_uncommitted_fragment(dirfrag_t basedirfrag, list<frag_t>&
       uf.old_frags.swap(old_frags);
       uf.committed = true;
     } else {
+      uf.ls->uncommitted_fragments.erase(basedirfrag);
       uncommitted_fragments.erase(basedirfrag);
     }
   }
index b9e7cfa823f858fcbe0974ae958c33578185f109..f5c83d5b18d1c019873dbf8076bf3258e6f40b76 100644 (file)
@@ -946,9 +946,11 @@ private:
   struct ufragment {
     int bits;
     bool committed;
+    LogSegment *ls;
+    list<Context*> waiters;
     list<frag_t> old_frags;
     bufferlist rollback;
-    ufragment() : bits(0), committed(false) {}
+    ufragment() : bits(0), committed(false), ls(NULL) {}
   };
   map<dirfrag_t, ufragment> uncommitted_fragments;
 
@@ -993,10 +995,14 @@ private:
   void handle_fragment_notify(MMDSFragmentNotify *m);
 
   void add_uncommitted_fragment(dirfrag_t basedirfrag, int bits, list<frag_t>& old_frag,
-                               bufferlist *rollback=NULL);
+                               LogSegment *ls, bufferlist *rollback=NULL);
   void finish_uncommitted_fragment(dirfrag_t basedirfrag, int op);
   void rollback_uncommitted_fragment(dirfrag_t basedirfrag, list<frag_t>& old_frags);
 public:
+  void wait_for_uncommitted_fragment(dirfrag_t dirfrag, Context *c) {
+    assert(uncommitted_fragments.count(dirfrag));
+    uncommitted_fragments[dirfrag].waiters.push_back(c);
+  }
   void split_dir(CDir *dir, int byn);
   void merge_dir(CInode *diri, frag_t fg);
   void rollback_uncommitted_fragments();
index ece1156fc58c13532b06ce6db1f8f4943f2bbbba..41a79f9fb38b3c435cc3723e46937a8f5833923c 100644 (file)
@@ -119,6 +119,14 @@ void LogSegment::try_to_expire(MDS *mds, C_GatherBuilder &gather_bld)
     mds->mdcache->wait_for_uncommitted_master(*p, gather_bld.new_sub());
   }
 
+  // uncommitted fragments
+  for (set<dirfrag_t>::iterator p = uncommitted_fragments.begin();
+       p != uncommitted_fragments.end();
+       ++p) {
+    dout(10) << "try_to_expire waiting for uncommitted fragment " << *p << dendl;
+    mds->mdcache->wait_for_uncommitted_fragment(*p, gather_bld.new_sub());
+  }
+
   // nudge scatterlocks
   for (elist<CInode*>::iterator p = dirty_dirfrag_dir.begin(); !p.end(); ++p) {
     CInode *in = *p;
@@ -2390,7 +2398,7 @@ void EFragment::replay(MDS *mds)
 
   switch (op) {
   case OP_PREPARE:
-    mds->mdcache->add_uncommitted_fragment(dirfrag_t(ino, basefrag), bits, orig_frags, &rollback);
+    mds->mdcache->add_uncommitted_fragment(dirfrag_t(ino, basefrag), bits, orig_frags, _segment, &rollback);
     // fall-thru
   case OP_ONESHOT:
     if (in)