mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-21 03:10:25 +08:00
ITS#7515 Fix nested txn touch of subpage/ovpage.
mdb_page_touch(): Don't touch a subpage, replacing with non-subpage. mdb_cursor_put(): Don't overwrite ancestor txn's dirty overflow page.
This commit is contained in:
parent
5bdf2aae6e
commit
a2ce25482a
@ -1633,7 +1633,7 @@ finish:
|
|||||||
SETPGNO(NODEPTR(mc->mc_pg[mc->mc_top-1], mc->mc_ki[mc->mc_top-1]), mp->mp_pgno);
|
SETPGNO(NODEPTR(mc->mc_pg[mc->mc_top-1], mc->mc_ki[mc->mc_top-1]), mp->mp_pgno);
|
||||||
else
|
else
|
||||||
mc->mc_db->md_root = mp->mp_pgno;
|
mc->mc_db->md_root = mp->mp_pgno;
|
||||||
} else if (mc->mc_txn->mt_parent) {
|
} else if (mc->mc_txn->mt_parent && !(mp->mp_flags & P_SUBP)) {
|
||||||
MDB_page *np;
|
MDB_page *np;
|
||||||
MDB_ID2 mid;
|
MDB_ID2 mid;
|
||||||
/* If txn has a parent, make sure the page is in our
|
/* If txn has a parent, make sure the page is in our
|
||||||
@ -5197,11 +5197,11 @@ current:
|
|||||||
if (F_ISSET(leaf->mn_flags, F_BIGDATA)) {
|
if (F_ISSET(leaf->mn_flags, F_BIGDATA)) {
|
||||||
MDB_page *omp;
|
MDB_page *omp;
|
||||||
pgno_t pg;
|
pgno_t pg;
|
||||||
int ovpages, dpages;
|
unsigned psize = mc->mc_txn->mt_env->me_psize;
|
||||||
|
int level, ovpages, dpages = OVPAGES(data->mv_size, psize);
|
||||||
|
|
||||||
dpages = OVPAGES(data->mv_size, mc->mc_txn->mt_env->me_psize);
|
|
||||||
memcpy(&pg, NODEDATA(leaf), sizeof(pg));
|
memcpy(&pg, NODEDATA(leaf), sizeof(pg));
|
||||||
if ((rc2 = mdb_page_get(mc->mc_txn, pg, &omp, NULL)) != 0)
|
if ((rc2 = mdb_page_get(mc->mc_txn, pg, &omp, &level)) != 0)
|
||||||
return rc2;
|
return rc2;
|
||||||
ovpages = omp->mp_pages;
|
ovpages = omp->mp_pages;
|
||||||
|
|
||||||
@ -5211,6 +5211,28 @@ current:
|
|||||||
* bother to try shrinking the page if the new data
|
* bother to try shrinking the page if the new data
|
||||||
* is smaller than the overflow threshold.
|
* is smaller than the overflow threshold.
|
||||||
*/
|
*/
|
||||||
|
if (level > 1) {
|
||||||
|
/* It is writable only in a parent txn */
|
||||||
|
size_t sz = (size_t) psize * ovpages, off;
|
||||||
|
MDB_page *np = mdb_page_malloc(mc, ovpages);
|
||||||
|
MDB_ID2 id2;
|
||||||
|
if (!np)
|
||||||
|
return ENOMEM;
|
||||||
|
id2.mid = pg;
|
||||||
|
id2.mptr = np;
|
||||||
|
mdb_mid2l_insert(mc->mc_txn->mt_u.dirty_list, &id2);
|
||||||
|
if (!(flags & MDB_RESERVE)) {
|
||||||
|
/* Copy end of page, adjusting alignment so
|
||||||
|
* compiler may copy words instead of bytes.
|
||||||
|
*/
|
||||||
|
off = (PAGEHDRSZ + data->mv_size) & -sizeof(size_t);
|
||||||
|
memcpy((size_t *)((char *)np + off),
|
||||||
|
(size_t *)((char *)omp + off), sz - off);
|
||||||
|
sz = PAGEHDRSZ;
|
||||||
|
}
|
||||||
|
memcpy(np, omp, sz); /* Copy beginning of page */
|
||||||
|
omp = np;
|
||||||
|
}
|
||||||
SETDSZ(leaf, data->mv_size);
|
SETDSZ(leaf, data->mv_size);
|
||||||
if (F_ISSET(flags, MDB_RESERVE))
|
if (F_ISSET(flags, MDB_RESERVE))
|
||||||
data->mv_data = METADATA(omp);
|
data->mv_data = METADATA(omp);
|
||||||
|
Loading…
Reference in New Issue
Block a user