]> git.sur5r.net Git - openldap/commitdiff
More for prev commit
authorHoward Chu <hyc@symas.com>
Tue, 11 Dec 2012 20:46:17 +0000 (12:46 -0800)
committerHoward Chu <hyc@symas.com>
Tue, 11 Dec 2012 20:46:17 +0000 (12:46 -0800)
Use the latest meta page

libraries/liblmdb/mdb.c

index b25c372fb7c55d80c592b5b6a1423d19f1b43180..4492a7603070e3a4cb8b1e4548c04bbeb94a9f6e 100644 (file)
@@ -2416,47 +2416,61 @@ mdb_env_read_header(MDB_env *env, MDB_meta *meta)
        MDB_pagebuf     pbuf;
        MDB_page        *p;
        MDB_meta        *m;
-       int              rc, err;
+       int              i, rc, err;
 
        /* We don't know the page size yet, so use a minimum value.
+        * Read both meta pages so we can use the latest one.
         */
 
+       for (i=0; i<2; i++) {
 #ifdef _WIN32
-       if (!ReadFile(env->me_fd, &pbuf, MDB_PAGESIZE, (DWORD *)&rc, NULL) || rc == 0)
+               if (!ReadFile(env->me_fd, &pbuf, MDB_PAGESIZE, (DWORD *)&rc, NULL) || rc == 0)
 #else
-       if ((rc = read(env->me_fd, &pbuf, MDB_PAGESIZE)) == 0)
+               if ((rc = read(env->me_fd, &pbuf, MDB_PAGESIZE)) == 0)
 #endif
-       {
-               return ENOENT;
-       }
-       else if (rc != MDB_PAGESIZE) {
-               err = ErrCode();
-               if (rc > 0)
-                       err = MDB_INVALID;
-               DPRINTF("read: %s", strerror(err));
-               return err;
-       }
+               {
+                       return ENOENT;
+               }
+               else if (rc != MDB_PAGESIZE) {
+                       err = ErrCode();
+                       if (rc > 0)
+                               err = MDB_INVALID;
+                       DPRINTF("read: %s", strerror(err));
+                       return err;
+               }
 
-       p = (MDB_page *)&pbuf;
+               p = (MDB_page *)&pbuf;
 
-       if (!F_ISSET(p->mp_flags, P_META)) {
-               DPRINTF("page %zu not a meta page", p->mp_pgno);
-               return MDB_INVALID;
-       }
+               if (!F_ISSET(p->mp_flags, P_META)) {
+                       DPRINTF("page %zu not a meta page", p->mp_pgno);
+                       return MDB_INVALID;
+               }
 
-       m = METADATA(p);
-       if (m->mm_magic != MDB_MAGIC) {
-               DPUTS("meta has invalid magic");
-               return MDB_INVALID;
-       }
+               m = METADATA(p);
+               if (m->mm_magic != MDB_MAGIC) {
+                       DPUTS("meta has invalid magic");
+                       return MDB_INVALID;
+               }
 
-       if (m->mm_version != MDB_VERSION) {
-               DPRINTF("database is version %u, expected version %u",
-                   m->mm_version, MDB_VERSION);
-               return MDB_VERSION_MISMATCH;
-       }
+               if (m->mm_version != MDB_VERSION) {
+                       DPRINTF("database is version %u, expected version %u",
+                               m->mm_version, MDB_VERSION);
+                       return MDB_VERSION_MISMATCH;
+               }
 
-       memcpy(meta, m, sizeof(*m));
+               if (i) {
+                       if (m->mm_txnid > meta->mm_txnid)
+                               memcpy(meta, m, sizeof(*m));
+               } else {
+                       memcpy(meta, m, sizeof(*m));
+#ifdef _WIN32
+                       if (SetFilePointer(env->me_fd, meta->mm_psize, NULL, FILE_BEGIN) != meta->mm_psize)
+#else
+                       if (lseek(env->me_fd, meta->mm_psize, SEEK_SET) != meta->mm_psize)
+#endif
+                               return ErrCode();
+               }
+       }
        return 0;
 }