]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
segment trimming race bug
authorsageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Thu, 8 Nov 2007 23:39:45 +0000 (23:39 +0000)
committersageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Thu, 8 Nov 2007 23:39:45 +0000 (23:39 +0000)
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@2040 29311d96-e01e-0410-9327-a35deaab8ce9

branches/sage/mds/TODO
branches/sage/mds/mds/LogSegment.h
branches/sage/mds/mds/MDCache.cc
branches/sage/mds/mds/MDLog.cc
branches/sage/mds/mds/MDS.cc
branches/sage/mds/mds/Server.cc
branches/sage/mds/osdc/Journaler.h

index caf03911846fa847444320f61e859aa09156e2d8..c970620074d9f7113f59f388c84587c5c94690de 100644 (file)
@@ -76,6 +76,9 @@ mds
 - detect and deal with client failure
   - failure during reconnect vs clientmap.  although probalby the whole thing needs a larger overhaul...
 
+- inode.rmtime (recursive mtime)
+- make inode.size reflect directory size (number of entries)
+
 - inode.max_size
 - inode.allocated_size
  
index e73f5f8b61b9ccf1b0bff51da4117f4ee31623cb..c4cf1d50897ff3ebdde33bb512cd87a80f0d2c61 100644 (file)
@@ -30,7 +30,7 @@ class MDSlaveUpdate;
 
 class LogSegment {
  public:
-  off_t offset;
+  off_t offset, end;
   int num_events;
 
   // dirty items
@@ -61,7 +61,7 @@ class LogSegment {
   C_Gather *try_to_expire(MDS *mds);
 
   // cons
-  LogSegment(off_t off) : offset(off), num_events(0),
+  LogSegment(off_t off) : offset(off), end(off), num_events(0),
                          allocv(0), clientmapv(0), anchortablev(0) 
   { }
 };
index be8bbb800aa77e54872615ee2460809d35b6a28b..59a7008d4af9d3a03a30ab66ee47727a4cd0ee32 100644 (file)
@@ -2813,8 +2813,8 @@ public:
 };
 
 /* purge_inode in
- * will be called by on unlink or rmdir or truncate
- * caller responsible for journaling an appropriate EUpdate
+ * will be called by on unlink or rmdir or truncate or purge
+ * caller responsible for journaling a matching EUpdate
  */
 void MDCache::purge_inode(CInode *in, off_t newsize, off_t oldsize, LogSegment *ls)
 {
index eeea99c7217512fd002785a793b812fe833180ac..52c50ff82a4fcd75f3a4ee472e41ed1357d0815a 100644 (file)
@@ -170,9 +170,11 @@ void MDLog::submit_entry( LogEvent *le, Context *c )
     // journal it.
     journaler->append_entry(bl);  // bl is destroyed.
   }
-  
+
+  le->_segment->end = journaler->get_write_pos();
+
   delete le;
-  
+
   if (logger) {
     logger->inc("evadd");
     logger->set("ev", num_events);
@@ -343,6 +345,9 @@ void MDLog::_expired(LogSegment *ls)
 
   if (!capped && ls == get_current_segment()) {
     dout(5) << "_expired not expiring " << ls->offset << ", last one and !capped" << dendl;
+  } else if (ls->end > journaler->get_write_ack_pos()) {
+    dout(5) << "_expired not expiring " << ls->offset << ", not fully flushed yet, ack "
+           << journaler->get_write_ack_pos() << " < end " << ls->end << dendl;
   } else {
     // expired.
     expired_segments.insert(ls);
@@ -467,6 +472,7 @@ void MDLog::_replay_thread()
               << " : " << *le << dendl;
       le->_segment = get_current_segment();    // replay may need this
       le->_segment->num_events++;
+      le->_segment->end = journaler->get_read_pos();
       num_events++;
 
       le->replay(mds);
index 0ec62b7f4ed05a5868b4db025d12480a3001af92..3a759518b3c47e98ce67260866e444e55d0ccb7f 100644 (file)
@@ -1109,7 +1109,7 @@ void MDS::my_dispatch(Message *m)
 
 
   // HACK FOR NOW
-  if (is_active()) {
+  if (is_active() || is_stopping()) {
     // flush log to disk after every op.  for now.
     mdlog->flush();
 
index e15d0ecde030b11d85b7971f9536da50ab67005c..b2fce5779d14ede3f67ccb279795a8a6de4fd14d 100644 (file)
@@ -1642,9 +1642,6 @@ void Server::handle_client_readdir(MDRequest *mdr)
     }
     assert(in);
 
-    
-    assert(in);
-
     dout(12) << "including inode " << *in << dendl;
     
     // add this dentry + inodeinfo
index a90ec5f9e348ff519692fc8902a5df3c7efe025e..7f7a5753ad708f5ecf592c9421e644ab29d499e6 100644 (file)
@@ -205,6 +205,7 @@ public:
   bool is_active() { return state == STATE_ACTIVE; }
 
   off_t get_write_pos() const { return write_pos; }
+  off_t get_write_ack_pos() const { return ack_pos; }
   off_t get_read_pos() const { return read_pos; }
   off_t get_expire_pos() const { return expire_pos; }
   off_t get_trimmed_pos() const { return trimmed_pos; }