]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: tolerate bad sessionmap during journal replay
authorYan, Zheng <zheng.z.yan@intel.com>
Sun, 27 Apr 2014 03:53:13 +0000 (11:53 +0800)
committerYan, Zheng <zheng.z.yan@intel.com>
Tue, 6 May 2014 23:10:16 +0000 (07:10 +0800)
Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
src/mds/journal.cc

index 323d52699d3ddc99fdb7c91d192dad9c97e89a7a..39e61e78eef1c47b437d9e3f880d1a97a168dd04 100644 (file)
@@ -1332,36 +1332,49 @@ void EMetaBlob::replay(MDS *mds, LogSegment *logseg, MDSlaveUpdate *slaveup)
     if (mds->sessionmap.version >= sessionmapv) {
       dout(10) << "EMetaBlob.replay sessionmap v " << sessionmapv
               << " <= table " << mds->sessionmap.version << dendl;
-    } else {
-      dout(10) << "EMetaBlob.replay sessionmap v" << sessionmapv
+    } else if (mds->sessionmap.version + 2 >= sessionmapv) {
+      dout(10) << "EMetaBlob.replay sessionmap v " << sessionmapv
               << " -(1|2) == table " << mds->sessionmap.version
               << " prealloc " << preallocated_inos
               << " used " << used_preallocated_ino
               << dendl;
       Session *session = mds->sessionmap.get_session(client_name);
-      assert(session);
-      dout(20) << " (session prealloc " << session->info.prealloc_inos << ")" << dendl;
-      if (used_preallocated_ino) {
-       if (session->info.prealloc_inos.empty()) {
-         // HRM: badness in the journal
-         mds->clog.warn() << " replayed op " << client_reqs << " on session for " << client_name
-                          << " with empty prealloc_inos\n";
-       } else {
-         inodeno_t next = session->next_ino();
-         inodeno_t i = session->take_ino(used_preallocated_ino);
-         if (next != i)
-           mds->clog.warn() << " replayed op " << client_reqs << " used ino " << i
-                            << " but session next is " << next << "\n";
-         assert(i == used_preallocated_ino);
-         session->info.used_inos.clear();
+      if (session) {
+       dout(20) << " (session prealloc " << session->info.prealloc_inos << ")" << dendl;
+       if (used_preallocated_ino) {
+         if (session->info.prealloc_inos.empty()) {
+           // HRM: badness in the journal
+           mds->clog.warn() << " replayed op " << client_reqs << " on session for "
+                            << client_name << " with empty prealloc_inos\n";
+         } else {
+           inodeno_t next = session->next_ino();
+           inodeno_t i = session->take_ino(used_preallocated_ino);
+           if (next != i)
+             mds->clog.warn() << " replayed op " << client_reqs << " used ino " << i
+                              << " but session next is " << next << "\n";
+           assert(i == used_preallocated_ino);
+           session->info.used_inos.clear();
+         }
+         mds->sessionmap.projected = ++mds->sessionmap.version;
        }
-       mds->sessionmap.projected = ++mds->sessionmap.version;
-      }
-      if (preallocated_inos.size()) {
-       session->info.prealloc_inos.insert(preallocated_inos);
-       mds->sessionmap.projected = ++mds->sessionmap.version;
+       if (!preallocated_inos.empty()) {
+         session->info.prealloc_inos.insert(preallocated_inos);
+         mds->sessionmap.projected = ++mds->sessionmap.version;
+       }
+      } else {
+       dout(10) << "EMetaBlob.replay no session for " << client_name << dendl;
+       if (used_preallocated_ino)
+         mds->sessionmap.projected = ++mds->sessionmap.version;
+       if (!preallocated_inos.empty())
+         mds->sessionmap.projected = ++mds->sessionmap.version;
       }
       assert(sessionmapv == mds->sessionmap.version);
+    } else {
+      mds->clog.error() << "journal replay sessionmap v " << sessionmapv
+                       << " -(1|2) > table " << mds->sessionmap.version << "\n";
+      assert(g_conf->mds_wipe_sessions);
+      mds->sessionmap.wipe();
+      mds->sessionmap.version = mds->sessionmap.projected = sessionmapv;
     }
   }