mirror of
https://github.com/isar/libmdbx.git
synced 2024-10-30 11:29:19 +08:00
mdbx: avoids EFAULT "Bad address" while copy-as-is if DB is swapped-out from RAM.
Change-Id: I711efc1c54a04745bd561bc5e1db5e6f6d8b7115
This commit is contained in:
parent
2e60256978
commit
6960c45e59
28
src/mdbx.c
28
src/mdbx.c
@ -11253,7 +11253,7 @@ int mdbx_put(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *data,
|
||||
}
|
||||
|
||||
#ifndef MDBX_WBUF
|
||||
#define MDBX_WBUF (1024 * 1024)
|
||||
#define MDBX_WBUF ((size_t)1024 * 1024)
|
||||
#endif
|
||||
#define MDBX_EOF 0x10 /* mdbx_env_copyfd1() is done reading */
|
||||
|
||||
@ -11632,12 +11632,13 @@ static int __cold mdbx_env_copy_asis(MDBX_env *env, MDBX_txn *read_txn,
|
||||
return rc;
|
||||
}
|
||||
|
||||
const size_t meta_bytes = pgno2bytes(env, NUM_METAS);
|
||||
/* Make a snapshot of meta-pages,
|
||||
* but writing ones after the data was flushed */
|
||||
memcpy(buffer, env->me_map, pgno2bytes(env, NUM_METAS));
|
||||
memcpy(buffer, env->me_map, meta_bytes);
|
||||
MDBX_meta *const headcopy = /* LY: get pointer to the spanshot copy */
|
||||
(MDBX_meta *)(buffer + ((uint8_t *)mdbx_meta_head(env) - env->me_map));
|
||||
const uint64_t size =
|
||||
const uint64_t whole_size =
|
||||
mdbx_roundup2(pgno2bytes(env, headcopy->mm_geo.now), env->me_os_psize);
|
||||
mdbx_txn_unlock(env);
|
||||
|
||||
@ -11645,12 +11646,19 @@ static int __cold mdbx_env_copy_asis(MDBX_env *env, MDBX_txn *read_txn,
|
||||
headcopy->mm_datasync_sign = mdbx_meta_sign(headcopy);
|
||||
|
||||
/* Copy the data */
|
||||
rc = mdbx_pwrite(fd, env->me_map + pgno2bytes(env, NUM_METAS),
|
||||
pgno2bytes(env, read_txn->mt_next_pgno - NUM_METAS),
|
||||
pgno2bytes(env, NUM_METAS));
|
||||
const size_t data_bytes = pgno2bytes(env, read_txn->mt_next_pgno);
|
||||
uint8_t *data_buffer = buffer + meta_bytes;
|
||||
for (size_t offset = meta_bytes;
|
||||
likely(rc == MDBX_SUCCESS) && offset < data_bytes;) {
|
||||
const size_t chunk =
|
||||
(MDBX_WBUF < data_bytes - offset) ? MDBX_WBUF : data_bytes - offset;
|
||||
memcpy(data_buffer, env->me_map + offset, chunk);
|
||||
rc = mdbx_pwrite(fd, data_buffer, chunk, offset);
|
||||
offset += chunk;
|
||||
}
|
||||
|
||||
if (likely(rc == MDBX_SUCCESS))
|
||||
rc = mdbx_ftruncate(fd, size);
|
||||
rc = mdbx_ftruncate(fd, whole_size);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -11667,8 +11675,10 @@ int __cold mdbx_env_copy2fd(MDBX_env *env, mdbx_filehandle_t fd,
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
|
||||
const size_t buffer_size = pgno2bytes(env, NUM_METAS) +
|
||||
((flags & MDBX_CP_COMPACT) ? MDBX_WBUF * 2 : 0);
|
||||
const size_t buffer_size =
|
||||
pgno2bytes(env, NUM_METAS) +
|
||||
((flags & MDBX_CP_COMPACT) ? MDBX_WBUF * 2 : MDBX_WBUF);
|
||||
|
||||
uint8_t *buffer = NULL;
|
||||
rc = mdbx_memalign_alloc(env->me_os_psize, buffer_size, (void **)&buffer);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
|
@ -544,7 +544,6 @@ int mdbx_pread(mdbx_filehandle_t fd, void *buf, size_t bytes, uint64_t offset) {
|
||||
if (bytes > MAX_WRITE)
|
||||
return MDBX_EINVAL;
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
||||
OVERLAPPED ov;
|
||||
ov.hEvent = 0;
|
||||
ov.Offset = (DWORD)offset;
|
||||
|
Loading…
Reference in New Issue
Block a user