ITS#9017 fixes for encryption

mdb.master3
Howard Chu 4 years ago
parent 1002664c33
commit d1814f7e5d
  1. 95
      libraries/liblmdb/mdb.c

@ -1446,6 +1446,7 @@ struct MDB_txn {
#define MDB_TXN_DIRTY 0x04 /**< must write, even if dirty list is empty */ #define MDB_TXN_DIRTY 0x04 /**< must write, even if dirty list is empty */
#define MDB_TXN_SPILLS 0x08 /**< txn or a parent has spilled pages */ #define MDB_TXN_SPILLS 0x08 /**< txn or a parent has spilled pages */
#define MDB_TXN_HAS_CHILD 0x10 /**< txn has an #MDB_txn.%mt_child */ #define MDB_TXN_HAS_CHILD 0x10 /**< txn has an #MDB_txn.%mt_child */
#define MDB_TXN_DIRTYNUM 0x20 /**< dirty list uses nump list */
/** most operations on the txn are currently illegal */ /** most operations on the txn are currently illegal */
#define MDB_TXN_BLOCKED (MDB_TXN_FINISHED|MDB_TXN_ERROR|MDB_TXN_HAS_CHILD) #define MDB_TXN_BLOCKED (MDB_TXN_FINISHED|MDB_TXN_ERROR|MDB_TXN_HAS_CHILD)
/** @} */ /** @} */
@ -1620,6 +1621,7 @@ struct MDB_env {
* Unused except for a dummy element when #MDB_WRITEMAP. * Unused except for a dummy element when #MDB_WRITEMAP.
*/ */
MDB_ID2L me_dirty_list; MDB_ID2L me_dirty_list;
int *me_dirty_nump;
/** Max number of freelist items that can fit in a single overflow page */ /** Max number of freelist items that can fit in a single overflow page */
int me_maxfree_1pg; int me_maxfree_1pg;
/** Max size of a node on a page */ /** Max size of a node on a page */
@ -1630,8 +1632,8 @@ struct MDB_env {
int me_live_reader; /**< have liveness lock in reader table */ int me_live_reader; /**< have liveness lock in reader table */
#ifdef _WIN32 #ifdef _WIN32
int me_pidquery; /**< Used in OpenProcess */ int me_pidquery; /**< Used in OpenProcess */
OVERLAPPED *ov; /**< Used for for overlapping I/O requests */ OVERLAPPED *me_ov; /**< Used for overlapping I/O requests */
int ovs; /**< Count of OVERLAPPEDs */ int me_ovs; /**< Count of MDB_overlaps */
#endif #endif
#ifdef MDB_USE_POSIX_MUTEX /* Posix mutexes reside in shared mem */ #ifdef MDB_USE_POSIX_MUTEX /* Posix mutexes reside in shared mem */
# define me_rmutex me_txns->mti_rmutex /**< Shared reader lock */ # define me_rmutex me_txns->mti_rmutex /**< Shared reader lock */
@ -2202,8 +2204,16 @@ mdb_dlist_free(MDB_txn *txn)
MDB_ID2L dl = txn->mt_u.dirty_list; MDB_ID2L dl = txn->mt_u.dirty_list;
unsigned i, n = dl[0].mid; unsigned i, n = dl[0].mid;
for (i = 1; i <= n; i++) { if (txn->mt_flags & MDB_TXN_DIRTYNUM) {
mdb_dpage_free(env, dl[i].mptr); int *dl_nump = env->me_dirty_nump;
for (i = 1; i <= n; i++) {
mdb_dpage_free_n(env, dl[i].mptr, dl_nump[i]);
}
txn->mt_flags ^= MDB_TXN_DIRTYNUM;
} else {
for (i = 1; i <= n; i++) {
mdb_dpage_free(env, dl[i].mptr);
}
} }
dl[0].mid = 0; dl[0].mid = 0;
} }
@ -3912,18 +3922,17 @@ mdb_page_flush(MDB_txn *txn, int keep)
MDB_env *env = txn->mt_env; MDB_env *env = txn->mt_env;
MDB_ID2L dl = txn->mt_u.dirty_list; MDB_ID2L dl = txn->mt_u.dirty_list;
unsigned psize = env->me_psize, j; unsigned psize = env->me_psize, j;
int i, pagecount = dl[0].mid, rc; int i, pagecount = dl[0].mid, rc, *dl_nump, nump = 1;
size_t size = 0; size_t size = 0;
MDB_OFF_T pos = 0; MDB_OFF_T pos = 0;
pgno_t pgno = 0; pgno_t pgno = 0;
MDB_page *dp = NULL; MDB_page *dp = NULL;
#if MDB_RPAGE_CACHE #if MDB_RPAGE_CACHE
int nump = 1;
MDB_page *encp; MDB_page *encp;
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
OVERLAPPED ov; OVERLAPPED *ov, *this_ov;
MDB_page *wdp; MDB_page *wdp;
int async_i = 0; int async_i = 0;
HANDLE fd = (env->me_flags & MDB_NOSYNC) ? env->me_fd : env->me_ovfd; HANDLE fd = (env->me_flags & MDB_NOSYNC) ? env->me_fd : env->me_ovfd;
#else #else
@ -3946,25 +3955,35 @@ mdb_page_flush(MDB_txn *txn, int keep)
goto done; goto done;
} }
/* setup nump list, flag that it's in use */
dl_nump = env->me_dirty_nump;
for (n=1; n<=pagecount; n++) {
dp = dl[n].mptr;
dl_nump[n] = IS_OVERFLOW(dp) ? dp->mp_pages : 1;
}
n = 0;
txn->mt_flags |= MDB_TXN_DIRTYNUM;
#ifdef _WIN32 #ifdef _WIN32
if (pagecount - keep >= env->ovs) { if (pagecount - keep >= env->me_ovs) {
/* ran out of room in ov array, and re-malloc, copy handles and free previous */ /* ran out of room in ov array, and re-malloc, copy handles and free previous */
int ovs = (pagecount - keep) * 1.5; /* provide extra padding to reduce number of re-allocations */ int ovs = (pagecount - keep) * 1.5; /* provide extra padding to reduce number of re-allocations */
int new_size = ovs * sizeof(OVERLAPPED); int new_size = ovs * sizeof(OVERLAPPED);
ov = malloc(new_size); ov = malloc(new_size);
if (ov == NULL) if (ov == NULL)
return ENOMEM; return ENOMEM;
int previous_size = env->ovs * sizeof(OVERLAPPED); int previous_size = env->me_ovs * sizeof(OVERLAPPED);
memcpy(ov, env->ov, previous_size); /* Copy previous OVERLAPPED data to retain event handles */ memcpy(ov, env->me_ov, previous_size); /* Copy previous OVERLAPPED data to retain event handles */
/* And clear rest of memory */ /* And clear rest of memory */
memset(&ov[env->ovs], 0, new_size - previous_size); memset(&ov[env->me_ovs], 0, new_size - previous_size);
if (env->ovs > 0) { if (env->me_ovs > 0) {
free(env->ov); /* release previous allocation */ free(env->me_ov); /* release previous allocation */
} }
env->ov = ov; env->me_ov = ov;
env->ovs = ovs; env->me_ovs = ovs;
} }
ov = env->me_ov;
#endif #endif
/* Write the pages */ /* Write the pages */
@ -3982,15 +4001,8 @@ mdb_page_flush(MDB_txn *txn, int keep)
dp->mp_txnid = txn->mt_txnid; dp->mp_txnid = txn->mt_txnid;
pos = pgno * psize; pos = pgno * psize;
size = psize; size = psize;
#if MDB_RPAGE_CACHE nump = dl_nump[i];
nump = 1; size *= nump;
if (IS_OVERFLOW(dp)) {
nump = dp->mp_pages;
size *= dp->mp_pages;
}
#else
if (IS_OVERFLOW(dp)) size *= dp->mp_pages;
#endif
} }
/* Write up to MDB_COMMIT_PAGES dirty pages at a time. */ /* Write up to MDB_COMMIT_PAGES dirty pages at a time. */
if (pos!=next_pos || n==MDB_COMMIT_PAGES || wsize+size>MAX_WRITE if (pos!=next_pos || n==MDB_COMMIT_PAGES || wsize+size>MAX_WRITE
@ -4013,7 +4025,7 @@ retry_write:
rc = 0; rc = 0;
/* Write previous page(s) */ /* Write previous page(s) */
#ifdef _WIN32 #ifdef _WIN32
OVERLAPPED *this_ov = &ov[async_i]; this_ov = &ov[async_i];
/* Clear status, and keep hEvent, we reuse that */ /* Clear status, and keep hEvent, we reuse that */
this_ov->Internal = 0; this_ov->Internal = 0;
this_ov->Offset = wpos & 0xffffffff; this_ov->Offset = wpos & 0xffffffff;
@ -4033,6 +4045,7 @@ retry_write:
DPRINTF(("WriteFile: %d", rc)); DPRINTF(("WriteFile: %d", rc));
return rc; return rc;
} }
rc = 0;
} }
async_i++; async_i++;
#else /* _WIN32 */ #else /* _WIN32 */
@ -4067,15 +4080,6 @@ retry_seek:
} }
} }
#endif /* _WIN32 */ #endif /* _WIN32 */
#if MDB_RPAGE_CACHE
if (env->me_encfunc) {
int j, num1;
for (j=0; j<n; j++) {
num1 = 1 + (iov[j].iov_len > psize);
mdb_dpage_free_n(env, (MDB_page *)iov[j].iov_base, num1);
}
}
#endif
if (rc) if (rc)
return rc; return rc;
n = 0; n = 0;
@ -4096,7 +4100,9 @@ retry_seek:
out.mv_size = size; out.mv_size = size;
out.mv_data = encp; out.mv_data = encp;
env->me_encfunc(&in, &out, env->me_enckey, 1); env->me_encfunc(&in, &out, env->me_enckey, 1);
mdb_dpage_free_n(env, dp, nump);
dp = encp; dp = encp;
dl[i].mptr = dp;
} }
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
@ -4143,9 +4149,6 @@ retry_seek:
if (!(env->me_flags & MDB_WRITEMAP)) { if (!(env->me_flags & MDB_WRITEMAP)) {
/* Don't free pages when using writemap (can only get here in NOSYNC mode in Windows) /* Don't free pages when using writemap (can only get here in NOSYNC mode in Windows)
* MIPS has cache coherency issues, this is a no-op everywhere else
* Note: for any size >= on-chip cache size, entire on-chip cache is
* flushed.
*/ */
for (i = keep; ++i <= pagecount; ) { for (i = keep; ++i <= pagecount; ) {
dp = dl[i].mptr; dp = dl[i].mptr;
@ -4155,9 +4158,10 @@ retry_seek:
dl[j].mid = dp->mp_pgno; dl[j].mid = dp->mp_pgno;
continue; continue;
} }
mdb_dpage_free(env, dp); mdb_dpage_free_n(env, dp, dl_nump[i]);
} }
} }
txn->mt_flags ^= MDB_TXN_DIRTYNUM;
done: done:
i--; i--;
@ -5205,7 +5209,7 @@ mdb_env_open2(MDB_env *env, int prev)
if (!NtCreateSection) if (!NtCreateSection)
return MDB_PROBLEM; return MDB_PROBLEM;
} }
env->ovs = 0; env->me_ovs = 0;
#endif /* _WIN32 */ #endif /* _WIN32 */
#ifdef BROKEN_FDATASYNC #ifdef BROKEN_FDATASYNC
@ -6010,6 +6014,8 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode
if (!((env->me_free_pgs = mdb_midl_alloc(MDB_IDL_UM_MAX)) && if (!((env->me_free_pgs = mdb_midl_alloc(MDB_IDL_UM_MAX)) &&
(env->me_dirty_list = calloc(dl_size, sizeof(MDB_ID2))))) (env->me_dirty_list = calloc(dl_size, sizeof(MDB_ID2)))))
rc = ENOMEM; rc = ENOMEM;
if (env->me_dirty_list && !(env->me_dirty_nump = malloc(dl_size * sizeof(int))))
rc = ENOMEM;
} }
env->me_flags = flags; env->me_flags = flags;
@ -6142,6 +6148,7 @@ mdb_env_close_active(MDB_env *env, int excl)
free(env->me_dbflags); free(env->me_dbflags);
free(env->me_path); free(env->me_path);
free(env->me_dirty_list); free(env->me_dirty_list);
free(env->me_dirty_nump);
#if MDB_RPAGE_CACHE #if MDB_RPAGE_CACHE
if (MDB_REMAPPING(env->me_flags)) { if (MDB_REMAPPING(env->me_flags)) {
if (env->me_txn0 && env->me_txn0->mt_rpages) if (env->me_txn0 && env->me_txn0->mt_rpages)
@ -6180,11 +6187,11 @@ mdb_env_close_active(MDB_env *env, int excl)
if (env->me_mfd != INVALID_HANDLE_VALUE) if (env->me_mfd != INVALID_HANDLE_VALUE)
(void) close(env->me_mfd); (void) close(env->me_mfd);
#ifdef _WIN32 #ifdef _WIN32
if (env->ovs > 0) { if (env->me_ovs > 0) {
for (i = 0; i < env->ovs; i++) { for (i = 0; i < env->me_ovs; i++) {
CloseHandle(env->ov[i].hEvent); CloseHandle(env->me_ov[i].hEvent);
} }
free(env->ov); free(env->me_ov);
} }
if (env->me_ovfd != INVALID_HANDLE_VALUE) if (env->me_ovfd != INVALID_HANDLE_VALUE)
(void) close(env->me_ovfd); (void) close(env->me_ovfd);

Loading…
Cancel
Save