Control: tags -1 +patch Hello!
Upstream has provided a patch now [1] which fixes the issue for me. It applies against both OpenLDAP 2.5.13 and 2.6.3 with fuzz and by fixing a single printf() statement manually. I am attaching the backported patch which applies cleanly. Thanks, Adrian
[1] https://git.openldap.org/openldap/openldap/-/merge_requests/582
-- .''`. John Paul Adrian Glaubitz : :' : Debian Developer `. `' Physicist `- GPG: 62FF 8A75 84E0 2956 9546 0006 7426 3B37 F5B5 F913
--- openldap-2.5.13+dfsg.orig/libraries/liblmdb/mdb.c +++ openldap-2.5.13+dfsg/libraries/liblmdb/mdb.c @@ -823,8 +823,6 @@ typedef struct MDB_page { #define P_KEEP 0x8000 /**< leave this page alone during spill */ /** @} */ uint16_t mp_flags; /**< @ref mdb_page */ -#define mp_lower mp_pb.pb.pb_lower -#define mp_upper mp_pb.pb.pb_upper #define mp_pages mp_pb.pb_pages union { struct { @@ -833,9 +831,26 @@ typedef struct MDB_page { } pb; uint32_t pb_pages; /**< number of overflow pages */ } mp_pb; - indx_t mp_ptrs[1]; /**< dynamic size */ + indx_t mp_ptrs[0]; /**< dynamic size */ } MDB_page; +/** Alternate page header, for 2-byte aligned access */ +typedef struct MDB_page2 { + uint16_t mp_p[sizeof(pgno_t)/2]; + uint16_t mp_pad; + uint16_t mp_flags; + indx_t mp_lower; + indx_t mp_upper; + indx_t mp_ptrs[0]; +} MDB_page2; + +#define MP_PGNO(p) (((MDB_page2 *)(void *)(p))->mp_p) +#define MP_PAD(p) (((MDB_page2 *)(void *)(p))->mp_pad) +#define MP_FLAGS(p) (((MDB_page2 *)(void *)(p))->mp_flags) +#define MP_LOWER(p) (((MDB_page2 *)(void *)(p))->mp_lower) +#define MP_UPPER(p) (((MDB_page2 *)(void *)(p))->mp_upper) +#define MP_PTRS(p) (((MDB_page2 *)(void *)(p))->mp_ptrs) + /** Size of the page header, excluding dynamic data at the end */ #define PAGEHDRSZ ((unsigned) offsetof(MDB_page, mp_ptrs)) @@ -846,10 +861,10 @@ typedef struct MDB_page { #define PAGEBASE ((MDB_DEVEL) ? PAGEHDRSZ : 0) /** Number of nodes on a page */ -#define NUMKEYS(p) (((p)->mp_lower - (PAGEHDRSZ-PAGEBASE)) >> 1) +#define NUMKEYS(p) ((MP_LOWER(p) - (PAGEHDRSZ-PAGEBASE)) >> 1) /** The amount of space remaining in the page */ -#define SIZELEFT(p) (indx_t)((p)->mp_upper - (p)->mp_lower) +#define SIZELEFT(p) (indx_t)(MP_UPPER(p) - MP_LOWER(p)) /** The percentage of space used in the page, in tenths of a percent. */ #define PAGEFILL(env, p) (1000L * ((env)->me_psize - PAGEHDRSZ - SIZELEFT(p)) / \ @@ -860,15 +875,15 @@ typedef struct MDB_page { #define FILL_THRESHOLD 250 /** Test if a page is a leaf page */ -#define IS_LEAF(p) F_ISSET((p)->mp_flags, P_LEAF) +#define IS_LEAF(p) F_ISSET(MP_FLAGS(p), P_LEAF) /** Test if a page is a LEAF2 page */ -#define IS_LEAF2(p) F_ISSET((p)->mp_flags, P_LEAF2) +#define IS_LEAF2(p) F_ISSET(MP_FLAGS(p), P_LEAF2) /** Test if a page is a branch page */ -#define IS_BRANCH(p) F_ISSET((p)->mp_flags, P_BRANCH) +#define IS_BRANCH(p) F_ISSET(MP_FLAGS(p), P_BRANCH) /** Test if a page is an overflow page */ -#define IS_OVERFLOW(p) F_ISSET((p)->mp_flags, P_OVERFLOW) +#define IS_OVERFLOW(p) F_ISSET(MP_FLAGS(p), P_OVERFLOW) /** Test if a page is a sub page */ -#define IS_SUBP(p) F_ISSET((p)->mp_flags, P_SUBP) +#define IS_SUBP(p) F_ISSET(MP_FLAGS(p), P_SUBP) /** The number of overflow pages needed to store the given size. */ #define OVPAGES(size, psize) ((PAGEHDRSZ-1 + (size)) / (psize) + 1) @@ -936,7 +951,7 @@ typedef struct MDB_node { #define LEAFSIZE(k, d) (NODESIZE + (k)->mv_size + (d)->mv_size) /** Address of node \b i in page \b p */ -#define NODEPTR(p, i) ((MDB_node *)((char *)(p) + (p)->mp_ptrs[i] + PAGEBASE)) +#define NODEPTR(p, i) ((MDB_node *)((char *)(p) + MP_PTRS(p)[i] + PAGEBASE)) /** Address of the key for the node */ #define NODEKEY(node) (void *)((node)->mn_data) @@ -964,6 +979,8 @@ typedef struct MDB_node { /** Copy a page number from src to dst */ #ifdef MISALIGNED_OK #define COPY_PGNO(dst,src) dst = src +#undef MP_PGNO +#define MP_PGNO(p) ((p)->mp_pgno) #else #if SIZE_MAX > 4294967295UL #define COPY_PGNO(dst,src) do { \ @@ -1554,7 +1571,7 @@ static pgno_t mdb_dbg_pgno(MDB_page *mp) { pgno_t ret; - COPY_PGNO(ret, mp->mp_pgno); + COPY_PGNO(ret, MP_PGNO(mp)); return ret; } @@ -1601,13 +1618,13 @@ void mdb_page_list(MDB_page *mp) { pgno_t pgno = mdb_dbg_pgno(mp); - const char *type, *state = (mp->mp_flags & P_DIRTY) ? ", dirty" : ""; + const char *type, *state = (MP_FLAGS(mp) & P_DIRTY) ? ", dirty" : ""; MDB_node *node; unsigned int i, nkeys, nsize, total = 0; MDB_val key; DKBUF; - switch (mp->mp_flags & (P_BRANCH|P_LEAF|P_LEAF2|P_META|P_OVERFLOW|P_SUBP)) { + switch (MP_FLAGS(mp) & (P_BRANCH|P_LEAF|P_LEAF2|P_META|P_OVERFLOW|P_SUBP)) { case P_BRANCH: type = "Branch page"; break; case P_LEAF: type = "Leaf page"; break; case P_LEAF|P_SUBP: type = "Sub-page"; break; @@ -1622,7 +1639,7 @@ mdb_page_list(MDB_page *mp) pgno, ((MDB_meta *)METADATA(mp))->mm_txnid); return; default: - fprintf(stderr, "Bad page %"Z"u flags 0x%X\n", pgno, mp->mp_flags); + fprintf(stderr, "Bad page %"Z"u flags 0x%X\n", pgno, MP_FLAGS(mp)); return; } @@ -1658,7 +1675,7 @@ mdb_page_list(MDB_page *mp) total = EVEN(total); } fprintf(stderr, "Total: header %d + contents %d + unused %d\n", - IS_LEAF2(mp) ? PAGEHDRSZ : PAGEBASE + mp->mp_lower, total, SIZELEFT(mp)); + IS_LEAF2(mp) ? PAGEHDRSZ : PAGEBASE + MP_LOWER(mp), total, SIZELEFT(mp)); } void @@ -1856,7 +1873,7 @@ mdb_page_loose(MDB_cursor *mc, MDB_page pgno_t pgno = mp->mp_pgno; MDB_txn *txn = mc->mc_txn; - if ((mp->mp_flags & P_DIRTY) && mc->mc_dbi != FREE_DBI) { + if ((MP_FLAGS(mp) & P_DIRTY) && mc->mc_dbi != FREE_DBI) { if (txn->mt_parent) { MDB_ID2 *dl = txn->mt_u.dirty_list; /* If txn has a parent, make sure the page is in our @@ -1885,7 +1902,7 @@ mdb_page_loose(MDB_cursor *mc, MDB_page NEXT_LOOSE_PAGE(mp) = txn->mt_loose_pgs; txn->mt_loose_pgs = mp; txn->mt_loose_count++; - mp->mp_flags |= P_LOOSE; + MP_FLAGS(mp) |= P_LOOSE; } else { int rc = mdb_midl_append(&txn->mt_free_pgs, pgno); if (rc) @@ -1925,14 +1942,14 @@ mdb_pages_xkeep(MDB_cursor *mc, unsigned mp = NULL; for (j=0; j<m3->mc_snum; j++) { mp = m3->mc_pg[j]; - if ((mp->mp_flags & Mask) == pflags) - mp->mp_flags ^= P_KEEP; + if ((MP_FLAGS(mp) & Mask) == pflags) + MP_FLAGS(mp) ^= P_KEEP; } mx = m3->mc_xcursor; /* Proceed to mx if it is at a sub-database */ if (! (mx && (mx->mx_cursor.mc_flags & C_INITIALIZED))) break; - if (! (mp && (mp->mp_flags & P_LEAF))) + if (! (mp && (MP_FLAGS(mp) & P_LEAF))) break; leaf = NODEPTR(mp, m3->mc_ki[j-1]); if (!(leaf->mn_flags & F_SUBDATA)) @@ -1952,8 +1969,8 @@ mdb_pages_xkeep(MDB_cursor *mc, unsigned continue; if ((rc = mdb_page_get(m0, pgno, &dp, &level)) != MDB_SUCCESS) break; - if ((dp->mp_flags & Mask) == pflags && level <= 1) - dp->mp_flags ^= P_KEEP; + if ((MP_FLAGS(dp) & Mask) == pflags && level <= 1) + MP_FLAGS(dp) ^= P_KEEP; } } } @@ -2056,7 +2073,7 @@ mdb_page_spill(MDB_cursor *m0, MDB_val * for (i=dl[0].mid; i && need; i--) { MDB_ID pn = dl[i].mid << 1; dp = dl[i].mptr; - if (dp->mp_flags & (P_LOOSE|P_KEEP)) + if (MP_FLAGS(dp) & (P_LOOSE|P_KEEP)) continue; /* Can't spill twice, make sure it's not already in a parent's * spill list. @@ -2067,7 +2084,7 @@ mdb_page_spill(MDB_cursor *m0, MDB_val * if (tx2->mt_spill_pgs) { j = mdb_midl_search(tx2->mt_spill_pgs, pn); if (j <= tx2->mt_spill_pgs[0] && tx2->mt_spill_pgs[j] == pn) { - dp->mp_flags |= P_KEEP; + MP_FLAGS(dp) |= P_KEEP; break; } } @@ -2327,7 +2344,7 @@ static void mdb_page_copy(MDB_page *dst, MDB_page *src, unsigned int psize) { enum { Align = sizeof(pgno_t) }; - indx_t upper = src->mp_upper, lower = src->mp_lower, unused = upper-lower; + indx_t upper = MP_UPPER(src), lower = MP_LOWER(src), unused = upper-lower; /* If page isn't full, just copy the used portion. Adjust * alignment so memcpy may copy words instead of bytes. @@ -2396,7 +2413,7 @@ mdb_page_unspill(MDB_txn *txn, MDB_page */ mdb_page_dirty(txn, np); - np->mp_flags |= P_DIRTY; + MP_FLAGS(np) |= P_DIRTY; *ret = np; break; } @@ -2418,7 +2435,7 @@ mdb_page_touch(MDB_cursor *mc) pgno_t pgno; int rc; - if (!F_ISSET(mp->mp_flags, P_DIRTY)) { + if (!F_ISSET(MP_FLAGS(mp), P_DIRTY)) { if (txn->mt_flags & MDB_TXN_SPILLS) { np = NULL; rc = mdb_page_unspill(txn, mp, &np); @@ -2475,7 +2492,7 @@ mdb_page_touch(MDB_cursor *mc) mdb_page_copy(np, mp, txn->mt_env->me_psize); np->mp_pgno = pgno; - np->mp_flags |= P_DIRTY; + MP_FLAGS(np) |= P_DIRTY; done: /* Adjust cursors pointing to mp */ @@ -3320,12 +3337,12 @@ mdb_page_flush(MDB_txn *txn, int keep) while (++i <= pagecount) { dp = dl[i].mptr; /* Don't flush this page yet */ - if (dp->mp_flags & (P_LOOSE|P_KEEP)) { - dp->mp_flags &= ~P_KEEP; + if (MP_FLAGS(dp) & (P_LOOSE|P_KEEP)) { + MP_FLAGS(dp) &= ~P_KEEP; dl[++j] = dl[i]; continue; } - dp->mp_flags &= ~P_DIRTY; + MP_FLAGS(dp) &= ~P_DIRTY; } goto done; } @@ -3335,14 +3352,14 @@ mdb_page_flush(MDB_txn *txn, int keep) if (++i <= pagecount) { dp = dl[i].mptr; /* Don't flush this page yet */ - if (dp->mp_flags & (P_LOOSE|P_KEEP)) { - dp->mp_flags &= ~P_KEEP; + if (MP_FLAGS(dp) & (P_LOOSE|P_KEEP)) { + MP_FLAGS(dp) &= ~P_KEEP; dl[i].mid = 0; continue; } pgno = dl[i].mid; /* clear dirty flag */ - dp->mp_flags &= ~P_DIRTY; + MP_FLAGS(dp) &= ~P_DIRTY; pos = pgno * psize; size = psize; if (IS_OVERFLOW(dp)) size *= dp->mp_pages; @@ -3784,12 +3801,12 @@ mdb_env_init_meta(MDB_env *env, MDB_meta return ENOMEM; p->mp_pgno = 0; - p->mp_flags = P_META; + MP_FLAGS(p) = P_META; *(MDB_meta *)METADATA(p) = *meta; q = (MDB_page *)((char *)p + psize); q->mp_pgno = 1; - q->mp_flags = P_META; + MP_FLAGS(q) = P_META; *(MDB_meta *)METADATA(q) = *meta; DO_PWRITE(rc, env->me_fd, p, psize * NUM_METAS, len, 0); @@ -5561,7 +5578,7 @@ ready: if (!IS_LEAF(mp)) { DPRINTF(("internal error, index points to a %02X page!?", - mp->mp_flags)); + MP_FLAGS(mp))); mc->mc_txn->mt_flags |= MDB_TXN_ERROR; return MDB_CORRUPTED; } @@ -5705,7 +5722,7 @@ mdb_ovpage_free(MDB_cursor *mc, MDB_page */ if (env->me_pghead && !txn->mt_parent && - ((mp->mp_flags & P_DIRTY) || + ((MP_FLAGS(mp) & P_DIRTY) || (sl && (x = mdb_midl_search(sl, pn)) <= sl[0] && sl[x] == pn))) { unsigned i, j; @@ -5714,7 +5731,7 @@ mdb_ovpage_free(MDB_cursor *mc, MDB_page rc = mdb_midl_need(&env->me_pghead, ovpages); if (rc) return rc; - if (!(mp->mp_flags & P_DIRTY)) { + if (!(MP_FLAGS(mp) & P_DIRTY)) { /* This page is no longer spilled */ if (x == sl[0]) sl[0]--; @@ -6061,7 +6078,7 @@ mdb_cursor_set(MDB_cursor *mc, MDB_val * mc->mc_ki[mc->mc_top] = 0; return MDB_NOTFOUND; } - if (mp->mp_flags & P_LEAF2) { + if (MP_FLAGS(mp) & P_LEAF2) { nodekey.mv_size = mc->mc_db->md_pad; nodekey.mv_data = LEAF2KEY(mp, 0, nodekey.mv_size); } else { @@ -6082,7 +6099,7 @@ mdb_cursor_set(MDB_cursor *mc, MDB_val * unsigned int i; unsigned int nkeys = NUMKEYS(mp); if (nkeys > 1) { - if (mp->mp_flags & P_LEAF2) { + if (MP_FLAGS(mp) & P_LEAF2) { nodekey.mv_data = LEAF2KEY(mp, nkeys-1, nodekey.mv_size); } else { @@ -6100,7 +6117,7 @@ mdb_cursor_set(MDB_cursor *mc, MDB_val * if (rc < 0) { if (mc->mc_ki[mc->mc_top] < NUMKEYS(mp)) { /* This is definitely the right page, skip search_page */ - if (mp->mp_flags & P_LEAF2) { + if (MP_FLAGS(mp) & P_LEAF2) { nodekey.mv_data = LEAF2KEY(mp, mc->mc_ki[mc->mc_top], nodekey.mv_size); } else { @@ -6663,7 +6680,7 @@ mdb_cursor_put(MDB_cursor *mc, MDB_val * *mc->mc_dbflag |= DB_DIRTY; if ((mc->mc_db->md_flags & (MDB_DUPSORT|MDB_DUPFIXED)) == MDB_DUPFIXED) - np->mp_flags |= P_LEAF2; + MP_FLAGS(np) |= P_LEAF2; mc->mc_flags |= C_INITIALIZED; } else { /* make sure all cursor pages are writable */ @@ -6685,7 +6702,7 @@ mdb_cursor_put(MDB_cursor *mc, MDB_val * fp_flags = P_LEAF|P_DIRTY; fp = env->me_pbuf; fp->mp_pad = data->mv_size; /* used if MDB_DUPFIXED */ - fp->mp_lower = fp->mp_upper = (PAGEHDRSZ-PAGEBASE); + MP_LOWER(fp) = MP_UPPER(fp) = (PAGEHDRSZ-PAGEBASE); olddata.mv_size = PAGEHDRSZ; goto prep_subDB; } @@ -6761,18 +6778,18 @@ more: dkey.mv_data = memcpy(fp+1, olddata.mv_data, olddata.mv_size); /* Make sub-page header for the dup items, with dummy body */ - fp->mp_flags = P_LEAF|P_DIRTY|P_SUBP; - fp->mp_lower = (PAGEHDRSZ-PAGEBASE); + MP_FLAGS(fp) = P_LEAF|P_DIRTY|P_SUBP; + MP_LOWER(fp) = (PAGEHDRSZ-PAGEBASE); xdata.mv_size = PAGEHDRSZ + dkey.mv_size + data->mv_size; if (mc->mc_db->md_flags & MDB_DUPFIXED) { - fp->mp_flags |= P_LEAF2; + MP_FLAGS(fp) |= P_LEAF2; fp->mp_pad = data->mv_size; xdata.mv_size += 2 * data->mv_size; /* leave space for 2 more */ } else { xdata.mv_size += 2 * (sizeof(indx_t) + NODESIZE) + (dkey.mv_size & 1) + (data->mv_size & 1); } - fp->mp_upper = xdata.mv_size - PAGEBASE; + MP_UPPER(fp) = xdata.mv_size - PAGEBASE; olddata.mv_size = xdata.mv_size; /* pretend olddata is fp */ } else if (leaf->mn_flags & F_SUBDATA) { /* Data is on sub-DB, just store it */ @@ -6795,8 +6812,8 @@ more: } /* FALLTHRU */ /* Big enough MDB_DUPFIXED sub-page */ case MDB_CURRENT: - fp->mp_flags |= P_DIRTY; - COPY_PGNO(fp->mp_pgno, mp->mp_pgno); + MP_FLAGS(fp) |= P_DIRTY; + COPY_PGNO(MP_PGNO(fp), MP_PGNO(mp)); mc->mc_xcursor->mx_cursor.mc_pg[0] = fp; flags |= F_DUPDATA; goto put_sub; @@ -6804,7 +6821,7 @@ more: xdata.mv_size = olddata.mv_size + offset; } - fp_flags = fp->mp_flags; + fp_flags = MP_FLAGS(fp); if (NODESIZE + NODEKSZ(leaf) + xdata.mv_size > env->me_nodemax) { /* Too big for a sub-page, convert to sub-DB */ fp_flags &= ~P_SUBP; @@ -6834,16 +6851,16 @@ prep_subDB: sub_root = mp; } if (mp != fp) { - mp->mp_flags = fp_flags | P_DIRTY; - mp->mp_pad = fp->mp_pad; - mp->mp_lower = fp->mp_lower; - mp->mp_upper = fp->mp_upper + offset; + MP_FLAGS(mp) = fp_flags | P_DIRTY; + MP_PAD(mp) = MP_PAD(fp); + MP_LOWER(mp) = MP_LOWER(fp); + MP_UPPER(mp) = MP_UPPER(fp) + offset; if (fp_flags & P_LEAF2) { memcpy(METADATA(mp), METADATA(fp), NUMKEYS(fp) * fp->mp_pad); } else { - memcpy((char *)mp + mp->mp_upper + PAGEBASE, (char *)fp + fp->mp_upper + PAGEBASE, - olddata.mv_size - fp->mp_upper - PAGEBASE); - memcpy((char *)(&mp->mp_ptrs), (char *)(&fp->mp_ptrs), NUMKEYS(fp) * sizeof(mp->mp_ptrs[0])); + memcpy((char *)mp + MP_UPPER(mp) + PAGEBASE, (char *)fp + MP_UPPER(fp) + PAGEBASE, + olddata.mv_size - MP_UPPER(fp) - PAGEBASE); + memcpy((char *)MP_PTRS(mp), (char *)MP_PTRS(fp), NUMKEYS(fp) * sizeof(mp->mp_ptrs[0])); for (i=0; i<NUMKEYS(fp); i++) mp->mp_ptrs[i] += offset; } @@ -6873,7 +6890,7 @@ current: /* Is the ov page large enough? */ if (ovpages >= dpages) { - if (!(omp->mp_flags & P_DIRTY) && + if (!(MP_FLAGS(omp) & P_DIRTY) && (level || (env->me_flags & MDB_WRITEMAP))) { rc = mdb_page_unspill(mc->mc_txn, omp, &omp); @@ -6882,7 +6899,7 @@ current: level = 0; /* dirty in this txn or clean */ } /* Is it dirty? */ - if (omp->mp_flags & P_DIRTY) { + if (MP_FLAGS(omp) & P_DIRTY) { /* yes, overwrite it. Note in this case we don't * bother to try shrinking the page if the new data * is smaller than the overflow threshold. @@ -7194,9 +7211,9 @@ mdb_page_new(MDB_cursor *mc, uint32_t fl return rc; DPRINTF(("allocated new mpage %"Z"u, page size %u", np->mp_pgno, mc->mc_txn->mt_env->me_psize)); - np->mp_flags = flags | P_DIRTY; - np->mp_lower = (PAGEHDRSZ-PAGEBASE); - np->mp_upper = mc->mc_txn->mt_env->me_psize - PAGEBASE; + MP_FLAGS(np) = flags | P_DIRTY; + MP_LOWER(np) = (PAGEHDRSZ-PAGEBASE); + MP_UPPER(np) = mc->mc_txn->mt_env->me_psize - PAGEBASE; if (IS_BRANCH(np)) mc->mc_db->md_branch_pages++; @@ -7291,7 +7308,7 @@ mdb_node_add(MDB_cursor *mc, indx_t indx void *ndata; DKBUF; - mdb_cassert(mc, mp->mp_upper >= mp->mp_lower); + mdb_cassert(mc, MP_UPPER(mp) >= MP_LOWER(mp)); DPRINTF(("add to %s %spage %"Z"u index %i, data size %"Z"u key size %"Z"u [%s]", IS_LEAF(mp) ? "leaf" : "branch", @@ -7310,8 +7327,8 @@ mdb_node_add(MDB_cursor *mc, indx_t indx memcpy(ptr, key->mv_data, ksize); /* Just using these for counting */ - mp->mp_lower += sizeof(indx_t); - mp->mp_upper -= ksize - sizeof(indx_t); + MP_LOWER(mp) += sizeof(indx_t); + MP_UPPER(mp) -= ksize - sizeof(indx_t); return MDB_SUCCESS; } @@ -7348,14 +7365,14 @@ mdb_node_add(MDB_cursor *mc, indx_t indx update: /* Move higher pointers up one slot. */ for (i = NUMKEYS(mp); i > indx; i--) - mp->mp_ptrs[i] = mp->mp_ptrs[i - 1]; + MP_PTRS(mp)[i] = MP_PTRS(mp)[i - 1]; /* Adjust free space offsets. */ - ofs = mp->mp_upper - node_size; - mdb_cassert(mc, ofs >= mp->mp_lower + sizeof(indx_t)); - mp->mp_ptrs[indx] = ofs; - mp->mp_upper = ofs; - mp->mp_lower += sizeof(indx_t); + ofs = MP_UPPER(mp) - node_size; + mdb_cassert(mc, ofs >= MP_LOWER(mp) + sizeof(indx_t)); + MP_PTRS(mp)[indx] = ofs; + MP_UPPER(mp) = ofs; + MP_LOWER(mp) += sizeof(indx_t); /* Write the node data. */ node = NODEPTR(mp, indx); @@ -7393,7 +7410,7 @@ update: full: DPRINTF(("not enough room in page %"Z"u, got %u ptrs", mdb_dbg_pgno(mp), NUMKEYS(mp))); - DPRINTF(("upper-lower = %u - %u = %"Z"d", mp->mp_upper,mp->mp_lower,room)); + DPRINTF(("upper-lower = %u - %u = %"Z"d", MP_UPPER(mp),MP_LOWER(mp),room)); DPRINTF(("node size = %"Z"u", node_size)); mc->mc_txn->mt_flags |= MDB_TXN_ERROR; return MDB_PAGE_FULL; @@ -7424,8 +7441,8 @@ mdb_node_del(MDB_cursor *mc, int ksize) base = LEAF2KEY(mp, indx, ksize); if (x) memmove(base, base + ksize, x * ksize); - mp->mp_lower -= sizeof(indx_t); - mp->mp_upper += ksize - sizeof(indx_t); + MP_LOWER(mp) -= sizeof(indx_t); + MP_UPPER(mp) += ksize - sizeof(indx_t); return; } @@ -7439,21 +7456,21 @@ mdb_node_del(MDB_cursor *mc, int ksize) } sz = EVEN(sz); - ptr = mp->mp_ptrs[indx]; + ptr = MP_PTRS(mp)[indx]; for (i = j = 0; i < numkeys; i++) { if (i != indx) { - mp->mp_ptrs[j] = mp->mp_ptrs[i]; - if (mp->mp_ptrs[i] < ptr) - mp->mp_ptrs[j] += sz; + MP_PTRS(mp)[j] = MP_PTRS(mp)[i]; + if (MP_PTRS(mp)[i] < ptr) + MP_PTRS(mp)[j] += sz; j++; } } - base = (char *)mp + mp->mp_upper + PAGEBASE; - memmove(base + sz, base, ptr - mp->mp_upper); + base = (char *)mp + MP_UPPER(mp) + PAGEBASE; + memmove(base + sz, base, ptr - MP_UPPER(mp)); - mp->mp_lower -= sizeof(indx_t); - mp->mp_upper += sz; + MP_LOWER(mp) -= sizeof(indx_t); + MP_UPPER(mp) += sz; } /** Compact the main page after deleting a node on a subpage. @@ -7482,15 +7499,15 @@ mdb_node_shrink(MDB_page *mp, indx_t ind } else { xp = (MDB_page *)((char *)sp + delta); /* destination subpage */ for (i = NUMKEYS(sp); --i >= 0; ) - xp->mp_ptrs[i] = sp->mp_ptrs[i] - delta; + MP_PTRS(xp)[i] = MP_PTRS(sp)[i] - delta; len = PAGEHDRSZ; } - sp->mp_upper = sp->mp_lower; - COPY_PGNO(sp->mp_pgno, mp->mp_pgno); + MP_UPPER(sp) = MP_LOWER(sp); + COPY_PGNO(MP_PGNO(sp), MP_PGNO(mp)); SETDSZ(node, nsize); /* Shift <lower nodes...initial part of subpage> upward */ - base = (char *)mp + mp->mp_upper + PAGEBASE; + base = (char *)mp + MP_UPPER(mp) + PAGEBASE; memmove(base + delta, base, (char *)sp + len - base); ptr = mp->mp_ptrs[indx]; @@ -7498,7 +7515,7 @@ mdb_node_shrink(MDB_page *mp, indx_t ind if (mp->mp_ptrs[i] <= ptr) mp->mp_ptrs[i] += delta; } - mp->mp_upper += delta; + MP_UPPER(mp) += delta; } /** Initial setup of a sorted-dups cursor. @@ -7557,7 +7574,7 @@ mdb_xcursor_init1(MDB_cursor *mc, MDB_no mx->mx_db.md_leaf_pages = 1; mx->mx_db.md_overflow_pages = 0; mx->mx_db.md_entries = NUMKEYS(fp); - COPY_PGNO(mx->mx_db.md_root, fp->mp_pgno); + COPY_PGNO(mx->mx_db.md_root, MP_PGNO(fp)); mx->mx_cursor.mc_snum = 1; mx->mx_cursor.mc_top = 0; mx->mx_cursor.mc_flags = C_INITIALIZED|C_SUB; @@ -7813,10 +7830,10 @@ mdb_update_key(MDB_cursor *mc, MDB_val * mp->mp_ptrs[i] -= delta; } - base = (char *)mp + mp->mp_upper + PAGEBASE; - len = ptr - mp->mp_upper + NODESIZE; + base = (char *)mp + MP_UPPER(mp) + PAGEBASE; + len = ptr - MP_UPPER(mp) + NODESIZE; memmove(base - delta, base, len); - mp->mp_upper -= delta; + MP_UPPER(mp) -= delta; node = NODEPTR(mp, indx); } @@ -8635,7 +8652,7 @@ mdb_page_split(MDB_cursor *mc, MDB_val * DKEY(newkey), mc->mc_ki[mc->mc_top], nkeys)); /* Create a right sibling. */ - if ((rc = mdb_page_new(mc, mp->mp_flags, 1, &rp))) + if ((rc = mdb_page_new(mc, MP_FLAGS(mp), 1, &rp))) return rc; rp->mp_pad = mp->mp_pad; DPRINTF(("new right sibling: page %"Z"u", rp->mp_pgno)); @@ -8700,10 +8717,10 @@ mdb_page_split(MDB_cursor *mc, MDB_val * split = LEAF2KEY(mp, split_indx, ksize); rsize = (nkeys - split_indx) * ksize; lsize = (nkeys - split_indx) * sizeof(indx_t); - mp->mp_lower -= lsize; - rp->mp_lower += lsize; - mp->mp_upper += rsize - lsize; - rp->mp_upper -= rsize - lsize; + MP_LOWER(mp) -= lsize; + MP_LOWER(rp) += lsize; + MP_UPPER(mp) += rsize - lsize; + MP_UPPER(rp) -= rsize - lsize; sepkey.mv_size = ksize; if (newindx == split_indx) { sepkey.mv_data = newkey->mv_data; @@ -8716,16 +8733,16 @@ mdb_page_split(MDB_cursor *mc, MDB_val * sepkey.mv_data = rp->mp_ptrs; memmove(ins+ksize, ins, (split_indx - mc->mc_ki[mc->mc_top]) * ksize); memcpy(ins, newkey->mv_data, ksize); - mp->mp_lower += sizeof(indx_t); - mp->mp_upper -= ksize - sizeof(indx_t); + MP_LOWER(mp) += sizeof(indx_t); + MP_UPPER(mp) -= ksize - sizeof(indx_t); } else { if (x) memcpy(rp->mp_ptrs, split, x * ksize); ins = LEAF2KEY(rp, x, ksize); memcpy(ins, newkey->mv_data, ksize); memcpy(ins+ksize, split + x * ksize, rsize - x * ksize); - rp->mp_lower += sizeof(indx_t); - rp->mp_upper -= ksize - sizeof(indx_t); + MP_LOWER(rp) += sizeof(indx_t); + MP_UPPER(rp) -= ksize - sizeof(indx_t); mc->mc_ki[mc->mc_top] = x; } } else { @@ -8745,9 +8762,9 @@ mdb_page_split(MDB_cursor *mc, MDB_val * goto done; } copy->mp_pgno = mp->mp_pgno; - copy->mp_flags = mp->mp_flags; - copy->mp_lower = (PAGEHDRSZ-PAGEBASE); - copy->mp_upper = env->me_psize - PAGEBASE; + MP_FLAGS(copy) = MP_FLAGS(mp); + MP_LOWER(copy) = (PAGEHDRSZ-PAGEBASE); + MP_UPPER(copy) = env->me_psize - PAGEBASE; /* prepare to insert */ for (i=0, j=0; i<nkeys; i++) { @@ -8917,10 +8934,10 @@ mdb_page_split(MDB_cursor *mc, MDB_val * nkeys = NUMKEYS(copy); for (i=0; i<nkeys; i++) mp->mp_ptrs[i] = copy->mp_ptrs[i]; - mp->mp_lower = copy->mp_lower; - mp->mp_upper = copy->mp_upper; + MP_LOWER(mp) = MP_LOWER(copy); + MP_UPPER(mp) = MP_UPPER(copy); memcpy(NODEPTR(mp, nkeys-1), NODEPTR(copy, nkeys-1), - env->me_psize - copy->mp_upper - PAGEBASE); + env->me_psize - MP_UPPER(copy) - PAGEBASE); /* reset back to original page */ if (newindx < split_indx) { @@ -9390,14 +9407,14 @@ mdb_env_copyfd1(MDB_env *env, HANDLE fd) mp = (MDB_page *)my.mc_wbuf[0]; memset(mp, 0, NUM_METAS * env->me_psize); mp->mp_pgno = 0; - mp->mp_flags = P_META; + MP_FLAGS(mp) = P_META; mm = (MDB_meta *)METADATA(mp); mdb_env_init_meta0(env, mm); mm->mm_address = env->me_metas[0]->mm_address; mp = (MDB_page *)(my.mc_wbuf[0] + env->me_psize); mp->mp_pgno = 1; - mp->mp_flags = P_META; + MP_FLAGS(mp) = P_META; *(MDB_meta *)METADATA(mp) = *mm; mm = (MDB_meta *)METADATA(mp);