mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-20 05:08:21 +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
|
#ifndef MDBX_WBUF
|
||||||
#define MDBX_WBUF (1024 * 1024)
|
#define MDBX_WBUF ((size_t)1024 * 1024)
|
||||||
#endif
|
#endif
|
||||||
#define MDBX_EOF 0x10 /* mdbx_env_copyfd1() is done reading */
|
#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;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const size_t meta_bytes = pgno2bytes(env, NUM_METAS);
|
||||||
/* Make a snapshot of meta-pages,
|
/* Make a snapshot of meta-pages,
|
||||||
* but writing ones after the data was flushed */
|
* 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 *const headcopy = /* LY: get pointer to the spanshot copy */
|
||||||
(MDBX_meta *)(buffer + ((uint8_t *)mdbx_meta_head(env) - env->me_map));
|
(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_roundup2(pgno2bytes(env, headcopy->mm_geo.now), env->me_os_psize);
|
||||||
mdbx_txn_unlock(env);
|
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);
|
headcopy->mm_datasync_sign = mdbx_meta_sign(headcopy);
|
||||||
|
|
||||||
/* Copy the data */
|
/* Copy the data */
|
||||||
rc = mdbx_pwrite(fd, env->me_map + pgno2bytes(env, NUM_METAS),
|
const size_t data_bytes = pgno2bytes(env, read_txn->mt_next_pgno);
|
||||||
pgno2bytes(env, read_txn->mt_next_pgno - NUM_METAS),
|
uint8_t *data_buffer = buffer + meta_bytes;
|
||||||
pgno2bytes(env, NUM_METAS));
|
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))
|
if (likely(rc == MDBX_SUCCESS))
|
||||||
rc = mdbx_ftruncate(fd, size);
|
rc = mdbx_ftruncate(fd, whole_size);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -11667,8 +11675,10 @@ int __cold mdbx_env_copy2fd(MDBX_env *env, mdbx_filehandle_t fd,
|
|||||||
if (unlikely(rc != MDBX_SUCCESS))
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
const size_t buffer_size = pgno2bytes(env, NUM_METAS) +
|
const size_t buffer_size =
|
||||||
((flags & MDBX_CP_COMPACT) ? MDBX_WBUF * 2 : 0);
|
pgno2bytes(env, NUM_METAS) +
|
||||||
|
((flags & MDBX_CP_COMPACT) ? MDBX_WBUF * 2 : MDBX_WBUF);
|
||||||
|
|
||||||
uint8_t *buffer = NULL;
|
uint8_t *buffer = NULL;
|
||||||
rc = mdbx_memalign_alloc(env->me_os_psize, buffer_size, (void **)&buffer);
|
rc = mdbx_memalign_alloc(env->me_os_psize, buffer_size, (void **)&buffer);
|
||||||
if (unlikely(rc != MDBX_SUCCESS))
|
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)
|
if (bytes > MAX_WRITE)
|
||||||
return MDBX_EINVAL;
|
return MDBX_EINVAL;
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
|
||||||
OVERLAPPED ov;
|
OVERLAPPED ov;
|
||||||
ov.hEvent = 0;
|
ov.hEvent = 0;
|
||||||
ov.Offset = (DWORD)offset;
|
ov.Offset = (DWORD)offset;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user