]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
More RAWPART support
authorHoward Chu <hyc@openldap.org>
Mon, 11 Jun 2018 09:12:03 +0000 (10:12 +0100)
committerHoward Chu <hyc@openldap.org>
Sat, 10 Oct 2020 15:21:57 +0000 (16:21 +0100)
Use mmap to read and initialize the meta pages, raw device
may not support read/write syscalls.

libraries/liblmdb/mdb.c

index df79f398526365395d74158e26f8f60e188db400..5b2284124228c4e94958cc9733de44fcbf85d10d 100644 (file)
@@ -4415,6 +4415,8 @@ fail:
        return rc;
 }
 
+static int ESECT mdb_env_map(MDB_env *env, void *addr);
+
 /** Read the environment parameters of a DB environment before
  * mapping it into memory.
  * @param[in] env the environment handle
@@ -4431,6 +4433,27 @@ mdb_env_read_header(MDB_env *env, int prev, MDB_meta *meta)
        int                     i, rc, off;
        enum { Size = sizeof(pbuf) };
 
+       if (env->me_flags & MDB_RAWPART) {
+#define VM_ALIGN       0x200000
+               env->me_mapsize += VM_ALIGN-1;
+               env->me_mapsize &= ~(VM_ALIGN-1);
+               env->me_psize = env->me_os_psize;
+               rc = mdb_env_map(env, NULL);
+               p = (MDB_page *)env->me_map;
+               for (i=0; i<NUM_METAS; i++) {
+                       if (!F_ISSET(p->mp_flags, P_META))
+                               return ENOENT;
+                       if (env->me_metas[i]->mm_magic != MDB_MAGIC)
+                               return MDB_INVALID;
+                       if (env->me_metas[i]->mm_version != MDB_DATA_VERSION)
+                               return MDB_VERSION_MISMATCH;
+                       if (i == 0 || env->me_metas[i]->mm_txnid > meta->mm_txnid)
+                               *meta = *env->me_metas[i];
+                       p = (MDB_page *)((char *)p + env->me_psize);
+               }
+               return 0;
+       }
+
        /* We don't know the page size yet, so use a minimum value.
         * Read both meta pages so we can use the latest one.
         */
@@ -4526,6 +4549,18 @@ mdb_env_init_meta(MDB_env *env, MDB_meta *meta)
 
        psize = env->me_psize;
 
+       if ((env->me_flags & (MDB_RAWPART|MDB_WRITEMAP)) == (MDB_RAWPART|MDB_WRITEMAP)) {
+               p = (MDB_page *)env->me_map;
+               p->mp_pgno = 0;
+               p->mp_flags = P_META;
+               *(MDB_meta *)METADATA(p) = *meta;
+               q = (MDB_page *)((char *)p + psize);
+               q->mp_pgno = 1;
+               q->mp_flags = P_META;
+               *(MDB_meta *)METADATA(q) = *meta;
+               return 0;
+       }
+
        p = calloc(NUM_METAS, psize);
        if (!p)
                return ENOMEM;
@@ -4800,6 +4835,8 @@ mdb_env_map(MDB_env *env, void *addr)
 #else  /* !_WIN32 */
        int mmap_flags = MAP_SHARED;
        int prot = PROT_READ;
+       if (flags & MDB_WRITEMAP)
+               prot |= PROT_WRITE;
 #ifdef MAP_NOSYNC      /* Used on FreeBSD */
        if (flags & MDB_NOSYNC)
                mmap_flags |= MAP_NOSYNC;
@@ -4815,7 +4852,6 @@ mdb_env_map(MDB_env *env, void *addr)
        } else
        {
        if (flags & MDB_WRITEMAP) {
-               prot |= PROT_WRITE;
                if (!(flags & MDB_RAWPART) && ftruncate(env->me_fd, env->me_mapsize) < 0)
                        return ErrCode();
        }
@@ -5957,7 +5993,7 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode
                if (rc)
                        return ErrCode();
                flags &= ~MDB_RAWPART;
-               if (S_ISBLK(st.st_mode))
+               if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode))
                        flags |= MDB_RAWPART | MDB_NOSUBDIR;
        }
 #endif