]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: alloc cleanup, log recoverable journal errors
authorSage Weil <sage@newdream.net>
Mon, 6 Jul 2009 17:03:12 +0000 (10:03 -0700)
committerSage Weil <sage@newdream.net>
Mon, 6 Jul 2009 17:03:12 +0000 (10:03 -0700)
src/mds/InoTable.cc
src/mds/MDS.cc
src/mds/MDSTable.h
src/mds/events/ESession.h
src/mds/journal.cc

index e1f38e74d88ed343f3a6d1b55aa148c8e4a25aac..82441125f2cfea456e9fb488b6f8850460f158fb 100644 (file)
@@ -64,7 +64,6 @@ void InoTable::apply_alloc_id(inodeno_t id)
 
 void InoTable::project_alloc_ids(interval_set<inodeno_t>& ids, int want) 
 {
-  dout(10) << "project_alloc_ids " << ids << " to " << projected_free << "/" << free << dendl;
   assert(is_active());
   while (want > 0) {
     inodeno_t start = projected_free.start();
@@ -76,6 +75,7 @@ void InoTable::project_alloc_ids(interval_set<inodeno_t>& ids, int want)
     ids.insert(start, num);
     want -= num;
   }
+  dout(10) << "project_alloc_ids " << ids << " to " << projected_free << "/" << free << dendl;
   ++projected_version;
 }
 void InoTable::apply_alloc_ids(interval_set<inodeno_t>& ids)
@@ -105,15 +105,31 @@ void InoTable::apply_release_ids(interval_set<inodeno_t>& ids)
 void InoTable::replay_alloc_id(inodeno_t id) 
 {
   dout(10) << "replay_alloc_id " << id << dendl;
-  free.erase(id);
-  projected_free.erase(id);
+  if (free.contains(id)) {
+    free.erase(id);
+    projected_free.erase(id);
+  } else {
+    stringstream ss;
+    ss << "journal replay alloc " << id << " not in free " << free;
+    mds->logclient.log(LOG_ERROR, ss);
+  }
   projected_version = ++version;
 }
 void InoTable::replay_alloc_ids(interval_set<inodeno_t>& ids) 
 {
   dout(10) << "replay_alloc_ids " << ids << dendl;
-  free.subtract(ids);
-  projected_free.subtract(ids);
+  interval_set<inodeno_t> is;
+  is.intersection_of(free, ids);
+  if (is == ids) {
+    free.subtract(ids);
+    projected_free.subtract(ids);
+  } else {
+    stringstream ss;
+    ss << "journal replay alloc " << ids << ", only " << is << " is in free " << free;
+    mds->logclient.log(LOG_ERROR, ss);
+    free.subtract(is);
+    projected_free.subtract(is);
+  }
   projected_version = ++version;
 }
 void InoTable::replay_release_ids(interval_set<inodeno_t>& ids) 
index 576d44fdf9d704e28786d2354f27519c9537b519..9ea4681dc9f240936c727b45eb3f7be6e37d702d 100644 (file)
@@ -372,6 +372,8 @@ void MDS::send_message_client(Message *m, entity_inst_t clientinst)
 
 int MDS::init()
 {
+  messenger->set_dispatcher(this);
+
   // get monmap
   monc->set_messenger(messenger);
   link_dispatcher(monc);
@@ -391,7 +393,6 @@ int MDS::init()
   reset_tick();
 
   // i'm ready!
-  messenger->set_dispatcher(this);
   link_dispatcher(&logclient);
 
   mds_lock.Unlock();
index 9d92be02be16de0b643c3801e9cb6484b6b365fa..466fafa297443e48742b375b236270e118215b1d 100644 (file)
@@ -52,6 +52,10 @@ public:
   version_t get_committing_version() { return committing_version; }
   version_t get_projected_version() { return projected_version; }
   
+  void force_replay_version(version_t v) {
+    version = projected_version = v;
+  }
+
   //version_t project_version() { return ++projected_version; }
   //version_t inc_version() { return ++version; }
 
index 4bb48fb4b7b2ac45c4b74b280933fcc99ccb1be8..4248d46beaea7198a95a81bbfb02c2c1574b55d4 100644 (file)
@@ -38,7 +38,8 @@ class ESession : public LogEvent {
     cmapv(v),
     inotablev(0) {
   }
-  ESession(entity_inst_t inst, bool o, version_t v, interval_set<inodeno_t>& i, version_t iv) :
+  ESession(entity_inst_t inst, bool o, version_t v,
+          const interval_set<inodeno_t>& i, version_t iv) :
     LogEvent(EVENT_SESSION),
     client_inst(inst),
     open(o),
index 9972b3dff730978dc23876a0de00e5661c6666c0..439a8ca3a86d2210b7295ce488f8a570aece3fd1 100644 (file)
@@ -553,6 +553,15 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg)
        mds->inotable->replay_alloc_id(allocated_ino);
       if (preallocated_inos.size())
        mds->inotable->replay_alloc_ids(preallocated_inos);
+
+      // [repair bad inotable updates]
+      if (inotablev > mds->inotable->get_version()) {
+       stringstream ss;
+       ss << "journal replay inotablev mismatch " << mds->inotable->get_version() << " -> " << inotablev;
+       mds->logclient.log(LOG_ERROR, ss);
+       mds->inotable->force_replay_version(inotablev);
+      }
+
       assert(inotablev == mds->inotable->get_version());
     }
   }