txnid_t mm_txnid; /**< txnid that committed this page */
} MDB_meta;
+ /** Buffer for a stack-allocated dirty page.
+ * The members define size and alignment, and silence type
+ * aliasing warnings. They are not used directly; that could
+ * mean incorrectly using several union members in parallel.
+ */
+typedef union MDB_pagebuf {
+ char mb_raw[MDB_PAGESIZE];
+ MDB_page mb_page;
+ struct {
+ char mm_pad[PAGEHDRSZ];
+ MDB_meta mm_meta;
+ } mb_metabuf;
+} MDB_pagebuf;
+
/** Auxiliary DB info.
* The information here is mostly static/read-only. There is
* only a single copy of this record in the environment.
static int
mdb_env_read_header(MDB_env *env, MDB_meta *meta)
{
- char page[MDB_PAGESIZE];
+ MDB_pagebuf pbuf;
MDB_page *p;
MDB_meta *m;
int rc, err;
*/
#ifdef _WIN32
- if (!ReadFile(env->me_fd, page, 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, page, MDB_PAGESIZE)) == 0)
+ if ((rc = read(env->me_fd, &pbuf, MDB_PAGESIZE)) == 0)
#endif
{
return ENOENT;
return err;
}
- p = (MDB_page *)page;
+ p = (MDB_page *)&pbuf;
if (!F_ISSET(p->mp_flags, P_META)) {
DPRINTF("page %zu not a meta page", p->mp_pgno);
unsigned int mcount = 0;
size_t nsize;
int rc, rc2;
- char pbuf[MDB_PAGESIZE];
+ MDB_pagebuf pbuf;
char dbuf[MAXKEYSIZE+1];
unsigned int nflags;
DKBUF;
/* create a fake page for the dup items */
memcpy(dbuf, dkey.mv_data, dkey.mv_size);
dkey.mv_data = dbuf;
- fp = (MDB_page *)pbuf;
+ fp = (MDB_page *)&pbuf;
fp->mp_pgno = mc->mc_pg[mc->mc_top]->mp_pgno;
fp->mp_flags = P_LEAF|P_DIRTY|P_SUBP;
fp->mp_lower = PAGEHDRSZ;
do_sub = 1;
rdata = &xdata;
xdata.mv_size = fp->mp_upper;
- xdata.mv_data = pbuf;
+ xdata.mv_data = fp;
flags |= F_DUPDATA;
goto new_sub;
}
/* no, just grow it */
rdata = &xdata;
xdata.mv_size = NODEDSZ(leaf) + offset;
- xdata.mv_data = pbuf;
- mp = (MDB_page *)pbuf;
+ xdata.mv_data = &pbuf;
+ mp = (MDB_page *)&pbuf;
mp->mp_pgno = mc->mc_pg[mc->mc_top]->mp_pgno;
flags |= F_DUPDATA;
}