From: Howard Chu Date: Wed, 18 Nov 2015 00:33:25 +0000 (+0000) Subject: ITS#8311 fix page_split from update_key X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=6d63afb1d9194cf1c0408b865f78e94efbf40990;p=openldap ITS#8311 fix page_split from update_key Check for top of stack. Usually the cursor only has height 1 when calling page_split, but not always. --- diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index 927c52c65c..f3c87bf5c8 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -6512,16 +6512,18 @@ fix_parent: * update branch key if there is a parent page */ if (mc->mc_top && !mc->mc_ki[mc->mc_top]) { - unsigned short top = mc->mc_top; + unsigned short dtop = 1; mc->mc_top--; /* slot 0 is always an empty key, find real slot */ - while (mc->mc_top && !mc->mc_ki[mc->mc_top]) + while (mc->mc_top && !mc->mc_ki[mc->mc_top]) { mc->mc_top--; + dtop++; + } if (mc->mc_ki[mc->mc_top]) rc2 = mdb_update_key(mc, key); else rc2 = MDB_SUCCESS; - mc->mc_top = top; + mc->mc_top += dtop; if (rc2) return rc2; } @@ -8370,12 +8372,14 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno rp->mp_pad = mp->mp_pad; DPRINTF(("new right sibling: page %"Z"u", rp->mp_pgno)); - if (mc->mc_snum < 2) { + if (mc->mc_top < 1) { if ((rc = mdb_page_new(mc, P_BRANCH, 1, &pp))) goto done; /* shift current top to make room for new parent */ - mc->mc_pg[1] = mc->mc_pg[0]; - mc->mc_ki[1] = mc->mc_ki[0]; + for (i=mc->mc_snum; i>0; i--) { + mc->mc_pg[i] = mc->mc_pg[i-1]; + mc->mc_ki[i] = mc->mc_ki[i-1]; + } mc->mc_pg[0] = pp; mc->mc_ki[0] = 0; mc->mc_db->md_root = pp->mp_pgno; @@ -8391,8 +8395,8 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno mc->mc_db->md_depth--; goto done; } - mc->mc_snum = 2; - mc->mc_top = 1; + mc->mc_snum++; + mc->mc_top++; ptop = 0; } else { ptop = mc->mc_top-1;