@ -1467,6 +1467,8 @@ struct MDB_env {
# endif
/** Failed to update the meta page. Probably an I/O error. */
# define MDB_FATAL_ERROR 0x80000000U
/** using a raw block device */
# define MDB_RAWPART 0x40000000U
/** Some fields are initialized. */
# define MDB_ENV_ACTIVE 0x20000000U
/** me_txkey is set */
@ -4038,6 +4040,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
@ -4054,6 +4058,31 @@ 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 ) ;
if ( rc ) {
DPRINTF ( ( " mdb_env_map: %s " , mdb_strerror ( rc ) ) ) ;
return rc ;
}
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 .
*/
@ -4081,6 +4110,8 @@ mdb_env_read_header(MDB_env *env, int prev, MDB_meta *meta)
p = ( MDB_page * ) & pbuf ;
if ( ! F_ISSET ( p - > mp_flags , P_META ) ) {
if ( env - > me_flags & MDB_RAWPART )
return ENOENT ;
DPRINTF ( ( " page % " Yu " not a meta page " , p - > mp_pgno ) ) ;
return MDB_INVALID ;
}
@ -4148,6 +4179,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 ;
@ -4410,7 +4453,7 @@ mdb_env_map(MDB_env *env, void *addr)
int prot = PROT_READ ;
if ( flags & MDB_WRITEMAP ) {
prot | = PROT_WRITE ;
if ( ftruncate ( env - > me_fd , env - > me_mapsize ) < 0 )
if ( ! ( flags & MDB_RAWPART ) & & ftruncate ( env - > me_fd , env - > me_mapsize ) < 0 )
return ErrCode ( ) ;
}
env - > me_map = mmap ( addr , env - > me_mapsize , prot , MAP_SHARED ,
@ -5448,6 +5491,17 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode
if ( rc )
goto leave ;
# endif
# endif
# ifndef _WIN32
{
struct stat st ;
flags & = ~ MDB_RAWPART ;
if ( ! stat ( path , & st ) & & ( S_ISBLK ( st . st_mode ) | | S_ISCHR ( st . st_mode ) ) ) {
flags | = MDB_RAWPART | MDB_NOSUBDIR ;
if ( ! env - > me_mapsize )
env - > me_mapsize = DEFAULT_MAPSIZE ;
}
}
# endif
flags | = MDB_ENV_ACTIVE ; /* tell mdb_env_close0() to clean up */
@ -7668,7 +7722,7 @@ more:
offset * = 4 ; /* space for 4 more */
break ;
}
/* FALLTHRU : Big enough MDB_DUPFIXED sub-page */
/* FALLTHRU *//* Big enough MDB_DUPFIXED sub-page */
case MDB_CURRENT :
fp - > mp_flags | = P_DIRTY ;
COPY_PGNO ( fp - > mp_pgno , mp - > mp_pgno ) ;