mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-22 15:49:34 -05:00
Fixes for loose pages
mdb_txn_commit(child): Give loose pages to parent. Use a pointer beyond the page header instead of mp_next, so we will not need to save/restore mp_pgno. This avoids a crash caused by references to mp_pgno.
This commit is contained in:
parent
b3e8c71dc7
commit
6ed295b256
1 changed files with 18 additions and 14 deletions
|
|
@ -655,7 +655,7 @@ typedef struct MDB_page {
|
||||||
#define mp_next mp_p.p_next
|
#define mp_next mp_p.p_next
|
||||||
union {
|
union {
|
||||||
pgno_t p_pgno; /**< page number */
|
pgno_t p_pgno; /**< page number */
|
||||||
void * p_next; /**< for in-memory list of freed structs */
|
struct MDB_page *p_next; /**< for in-memory list of freed pages */
|
||||||
} mp_p;
|
} mp_p;
|
||||||
uint16_t mp_pad;
|
uint16_t mp_pad;
|
||||||
/** @defgroup mdb_page Page Flags
|
/** @defgroup mdb_page Page Flags
|
||||||
|
|
@ -731,7 +731,7 @@ typedef struct MDB_page {
|
||||||
#define OVPAGES(size, psize) ((PAGEHDRSZ-1 + (size)) / (psize) + 1)
|
#define OVPAGES(size, psize) ((PAGEHDRSZ-1 + (size)) / (psize) + 1)
|
||||||
|
|
||||||
/** Link in #MDB_txn.%mt_loose_pages list */
|
/** Link in #MDB_txn.%mt_loose_pages list */
|
||||||
#define NEXT_LOOSE_PAGE(p) (*(MDB_page **)METADATA(p))
|
#define NEXT_LOOSE_PAGE(p) (*(MDB_page **)((p) + 2))
|
||||||
|
|
||||||
/** Header for a single key/data pair within a page.
|
/** Header for a single key/data pair within a page.
|
||||||
* Used in pages of type #P_BRANCH and #P_LEAF without #P_LEAF2.
|
* Used in pages of type #P_BRANCH and #P_LEAF without #P_LEAF2.
|
||||||
|
|
@ -1601,6 +1601,8 @@ mdb_page_loose(MDB_cursor *mc, MDB_page *mp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (loose) {
|
if (loose) {
|
||||||
|
DPRINTF(("loosen db %d page %"Z"u", DDBI(mc),
|
||||||
|
mp->mp_pgno));
|
||||||
NEXT_LOOSE_PAGE(mp) = mc->mc_txn->mt_loose_pgs;
|
NEXT_LOOSE_PAGE(mp) = mc->mc_txn->mt_loose_pgs;
|
||||||
mc->mc_txn->mt_loose_pgs = mp;
|
mc->mc_txn->mt_loose_pgs = mp;
|
||||||
mp->mp_flags |= P_LOOSE;
|
mp->mp_flags |= P_LOOSE;
|
||||||
|
|
@ -1623,7 +1625,7 @@ mdb_page_loose(MDB_cursor *mc, MDB_page *mp)
|
||||||
static int
|
static int
|
||||||
mdb_pages_xkeep(MDB_cursor *mc, unsigned pflags, int all)
|
mdb_pages_xkeep(MDB_cursor *mc, unsigned pflags, int all)
|
||||||
{
|
{
|
||||||
enum { Mask = P_SUBP|P_DIRTY|P_KEEP };
|
enum { Mask = P_SUBP|P_DIRTY|P_LOOSE|P_KEEP };
|
||||||
MDB_txn *txn = mc->mc_txn;
|
MDB_txn *txn = mc->mc_txn;
|
||||||
MDB_cursor *m3;
|
MDB_cursor *m3;
|
||||||
MDB_xcursor *mx;
|
MDB_xcursor *mx;
|
||||||
|
|
@ -1661,12 +1663,6 @@ mdb_pages_xkeep(MDB_cursor *mc, unsigned pflags, int all)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loose pages shouldn't be spilled */
|
|
||||||
for (dp = txn->mt_loose_pgs; dp; dp = NEXT_LOOSE_PAGE(dp)) {
|
|
||||||
if ((dp->mp_flags & Mask) == pflags)
|
|
||||||
dp->mp_flags ^= P_KEEP;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (all) {
|
if (all) {
|
||||||
/* Mark dirty root pages */
|
/* Mark dirty root pages */
|
||||||
for (i=0; i<txn->mt_numdbs; i++) {
|
for (i=0; i<txn->mt_numdbs; i++) {
|
||||||
|
|
@ -1780,7 +1776,7 @@ mdb_page_spill(MDB_cursor *m0, MDB_val *key, MDB_val *data)
|
||||||
for (i=dl[0].mid; i && need; i--) {
|
for (i=dl[0].mid; i && need; i--) {
|
||||||
MDB_ID pn = dl[i].mid << 1;
|
MDB_ID pn = dl[i].mid << 1;
|
||||||
dp = dl[i].mptr;
|
dp = dl[i].mptr;
|
||||||
if (dp->mp_flags & P_KEEP)
|
if (dp->mp_flags & (P_LOOSE|P_KEEP))
|
||||||
continue;
|
continue;
|
||||||
/* Can't spill twice, make sure it's not already in a parent's
|
/* Can't spill twice, make sure it's not already in a parent's
|
||||||
* spill list.
|
* spill list.
|
||||||
|
|
@ -1898,6 +1894,8 @@ mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp)
|
||||||
if (num == 1 && txn->mt_loose_pgs) {
|
if (num == 1 && txn->mt_loose_pgs) {
|
||||||
np = txn->mt_loose_pgs;
|
np = txn->mt_loose_pgs;
|
||||||
txn->mt_loose_pgs = NEXT_LOOSE_PAGE(np);
|
txn->mt_loose_pgs = NEXT_LOOSE_PAGE(np);
|
||||||
|
DPRINTF(("db %d use loose page %"Z"u", DDBI(mc),
|
||||||
|
np->mp_pgno));
|
||||||
*mp = np;
|
*mp = np;
|
||||||
return MDB_SUCCESS;
|
return MDB_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
@ -2951,8 +2949,8 @@ mdb_page_flush(MDB_txn *txn, int keep)
|
||||||
while (++i <= pagecount) {
|
while (++i <= pagecount) {
|
||||||
dp = dl[i].mptr;
|
dp = dl[i].mptr;
|
||||||
/* Don't flush this page yet */
|
/* Don't flush this page yet */
|
||||||
if (dp->mp_flags & P_KEEP) {
|
if (dp->mp_flags & (P_LOOSE|P_KEEP)) {
|
||||||
dp->mp_flags ^= P_KEEP;
|
dp->mp_flags &= ~P_KEEP;
|
||||||
dl[++j] = dl[i];
|
dl[++j] = dl[i];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -2966,8 +2964,8 @@ mdb_page_flush(MDB_txn *txn, int keep)
|
||||||
if (++i <= pagecount) {
|
if (++i <= pagecount) {
|
||||||
dp = dl[i].mptr;
|
dp = dl[i].mptr;
|
||||||
/* Don't flush this page yet */
|
/* Don't flush this page yet */
|
||||||
if (dp->mp_flags & P_KEEP) {
|
if (dp->mp_flags & (P_LOOSE|P_KEEP)) {
|
||||||
dp->mp_flags ^= P_KEEP;
|
dp->mp_flags &= ~P_KEEP;
|
||||||
dl[i].mid = 0;
|
dl[i].mid = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -3096,6 +3094,7 @@ mdb_txn_commit(MDB_txn *txn)
|
||||||
|
|
||||||
if (txn->mt_parent) {
|
if (txn->mt_parent) {
|
||||||
MDB_txn *parent = txn->mt_parent;
|
MDB_txn *parent = txn->mt_parent;
|
||||||
|
MDB_page **lp;
|
||||||
MDB_ID2L dst, src;
|
MDB_ID2L dst, src;
|
||||||
MDB_IDL pspill;
|
MDB_IDL pspill;
|
||||||
unsigned x, y, len, ps_len;
|
unsigned x, y, len, ps_len;
|
||||||
|
|
@ -3193,6 +3192,11 @@ mdb_txn_commit(MDB_txn *txn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Append our loose page list to parent's */
|
||||||
|
for (lp = &parent->mt_loose_pgs; *lp; lp = &NEXT_LOOSE_PAGE(lp))
|
||||||
|
;
|
||||||
|
*lp = txn->mt_loose_pgs;
|
||||||
|
|
||||||
parent->mt_child = NULL;
|
parent->mt_child = NULL;
|
||||||
mdb_midl_free(((MDB_ntxn *)txn)->mnt_pgstate.mf_pghead);
|
mdb_midl_free(((MDB_ntxn *)txn)->mnt_pgstate.mf_pghead);
|
||||||
free(txn);
|
free(txn);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue