mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-21 21:18:20 +08:00
mdbx: определение in-core БД (в tmpfs/ramfs/mfs) с отключением prefault-write.
Это вынужденный читинг для "починки" сравнительных бенчмарков при размещении БД в /dev/shm. Проблема в том, что актуальные ядра Linux для файлов размещенных в tmpfs возвращают mincore=false. В результате, в простейших бенчмарках видно двукратное снижение производительности, просто из-за вызовов write() выполняемых для prefault. Из-за этого, в таких синтетических тестах, новая libmdbx становится существенно медленнее предыдущих версий, в том числе LMDB.
This commit is contained in:
parent
69f7d6cdd8
commit
54b15d7e41
94
src/core.c
94
src/core.c
@ -5920,13 +5920,28 @@ __cold static void munlock_all(const MDBX_env *env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
__cold static unsigned default_rp_augment_limit(const MDBX_env *env) {
|
__cold static unsigned default_rp_augment_limit(const MDBX_env *env) {
|
||||||
/* default drp_augment_limit = ceil(npages / gold_ratio) */
|
/* default rp_augment_limit = ceil(npages / gold_ratio) */
|
||||||
const size_t augment = (env->me_dbgeo.now >> (env->me_psize2log + 10)) * 633u;
|
const size_t augment = (env->me_dbgeo.now >> (env->me_psize2log + 10)) * 633u;
|
||||||
eASSERT(env, augment < MDBX_PGL_LIMIT);
|
eASSERT(env, augment < MDBX_PGL_LIMIT);
|
||||||
return pnl_bytes2size(pnl_size2bytes(
|
return pnl_bytes2size(pnl_size2bytes(
|
||||||
(augment > MDBX_PNL_INITIAL) ? augment : MDBX_PNL_INITIAL));
|
(augment > MDBX_PNL_INITIAL) ? augment : MDBX_PNL_INITIAL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__cold static bool default_prefault_write(const MDBX_env *env) {
|
||||||
|
if (env->me_incore ||
|
||||||
|
(env->me_flags & (MDBX_WRITEMAP | MDBX_RDONLY)) != MDBX_WRITEMAP)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return !MDBX_MMAP_INCOHERENT_FILE_WRITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void adjust_defaults(MDBX_env *env) {
|
||||||
|
if (!env->me_options.flags.non_auto.rp_augment_limit)
|
||||||
|
env->me_options.rp_augment_limit = default_rp_augment_limit(env);
|
||||||
|
if (!env->me_options.flags.non_auto.prefault_write)
|
||||||
|
env->me_options.prefault_write = default_prefault_write(env);
|
||||||
|
}
|
||||||
|
|
||||||
__cold static int map_resize(MDBX_env *env, const pgno_t used_pgno,
|
__cold static int map_resize(MDBX_env *env, const pgno_t used_pgno,
|
||||||
const pgno_t size_pgno, const pgno_t limit_pgno,
|
const pgno_t size_pgno, const pgno_t limit_pgno,
|
||||||
const bool implicit) {
|
const bool implicit) {
|
||||||
@ -6120,8 +6135,7 @@ bailout:
|
|||||||
/* update env-geo to avoid influences */
|
/* update env-geo to avoid influences */
|
||||||
env->me_dbgeo.now = env->me_dxb_mmap.current;
|
env->me_dbgeo.now = env->me_dxb_mmap.current;
|
||||||
env->me_dbgeo.upper = env->me_dxb_mmap.limit;
|
env->me_dbgeo.upper = env->me_dxb_mmap.limit;
|
||||||
if (!env->me_options.flags.non_auto.rp_augment_limit)
|
adjust_defaults(env);
|
||||||
env->me_options.rp_augment_limit = default_rp_augment_limit(env);
|
|
||||||
#ifdef MDBX_USE_VALGRIND
|
#ifdef MDBX_USE_VALGRIND
|
||||||
if (prev_limit != env->me_dxb_mmap.limit || prev_map != env->me_map) {
|
if (prev_limit != env->me_dxb_mmap.limit || prev_map != env->me_map) {
|
||||||
VALGRIND_DISCARD(env->me_valgrind_handle);
|
VALGRIND_DISCARD(env->me_valgrind_handle);
|
||||||
@ -7044,26 +7058,15 @@ static __inline pgr_t page_alloc_finalize(MDBX_env *const env,
|
|||||||
* с диска. При этом запись на диск должна быть отложена адекватным ядром,
|
* с диска. При этом запись на диск должна быть отложена адекватным ядром,
|
||||||
* так как страница отображена в память в режиме чтения-записи и следом в
|
* так как страница отображена в память в режиме чтения-записи и следом в
|
||||||
* неё пишет ЦПУ. */
|
* неё пишет ЦПУ. */
|
||||||
const bool readahead_enabled = env->me_lck->mti_readahead_anchor & 1;
|
|
||||||
const pgno_t readahead_edge = env->me_lck->mti_readahead_anchor >> 1;
|
|
||||||
/* В случае если страница в памяти процесса, то излишняя запись может быть
|
/* В случае если страница в памяти процесса, то излишняя запись может быть
|
||||||
* достаточно дорогой. Кроме системного вызова и копирования данных, в особо
|
* достаточно дорогой. Кроме системного вызова и копирования данных, в особо
|
||||||
* одаренных ОС при этом могут включаться файловая система, выделяться
|
* одаренных ОС при этом могут включаться файловая система, выделяться
|
||||||
* временная страница, пополняться очереди асинхронного выполнения,
|
* временная страница, пополняться очереди асинхронного выполнения,
|
||||||
* обновляться PTE с последующей генерацией page-fault и чтением данных из
|
* обновляться PTE с последующей генерацией page-fault и чтением данных из
|
||||||
* грязной I/O очереди. Из-за этого штраф за лишнюю запись может быть
|
* грязной I/O очереди. Из-за этого штраф за лишнюю запись может быть
|
||||||
* сравним с избегаемым ненужным чтением.
|
* сравним с избегаемым ненужным чтением. */
|
||||||
*
|
if (env->me_prefault_write) {
|
||||||
* Проверка посредством minicore() существенно снижает затраты, но в
|
|
||||||
* простейших случаях (тривиальный бенчмарк) интегральная производительность
|
|
||||||
* становится вдвое меньше. А на платформах без minocore() и с проблемной
|
|
||||||
* подсистемой виртуальной памяти ситуация может быть многократно хуже.
|
|
||||||
* Поэтому избегаем затрат в ситуациях когда prefaukt-write скорее всего не
|
|
||||||
* нужна. Стоит подумать над дополнительными критериями. */
|
|
||||||
if (/* Не суетимся если GC почти пустая и БД маленькая */
|
|
||||||
(txn->mt_dbs[FREE_DBI].md_branch_pages || txn->mt_geo.now > 1234) &&
|
|
||||||
/* Не суетимся если страница в зоне включенного упреждающего чтения */
|
|
||||||
(!readahead_enabled || pgno + num > readahead_edge)) {
|
|
||||||
void *const pattern = ptr_disp(
|
void *const pattern = ptr_disp(
|
||||||
env->me_pbuf, need_clean ? env->me_psize : env->me_psize * 2);
|
env->me_pbuf, need_clean ? env->me_psize : env->me_psize * 2);
|
||||||
size_t file_offset = pgno2bytes(env, pgno);
|
size_t file_offset = pgno2bytes(env, pgno);
|
||||||
@ -7200,6 +7203,24 @@ static pgr_t page_alloc_slowpath(const MDBX_cursor *const mc, const size_t num,
|
|||||||
gc->mc_txn = txn;
|
gc->mc_txn = txn;
|
||||||
gc->mc_flags = 0;
|
gc->mc_flags = 0;
|
||||||
|
|
||||||
|
env->me_prefault_write = env->me_options.prefault_write;
|
||||||
|
if (env->me_prefault_write) {
|
||||||
|
/* Проверка посредством minicore() существенно снижает затраты, но в
|
||||||
|
* простейших случаях (тривиальный бенчмарк) интегральная производительность
|
||||||
|
* становится вдвое меньше. А на платформах без mincore() и с проблемной
|
||||||
|
* подсистемой виртуальной памяти ситуация может быть многократно хуже.
|
||||||
|
* Поэтому избегаем затрат в ситуациях когда prefaukt-write скорее всего не
|
||||||
|
* нужна. */
|
||||||
|
const bool readahead_enabled = env->me_lck->mti_readahead_anchor & 1;
|
||||||
|
const pgno_t readahead_edge = env->me_lck->mti_readahead_anchor >> 1;
|
||||||
|
if (/* Не суетимся если GC почти пустая и БД маленькая */
|
||||||
|
(txn->mt_dbs[FREE_DBI].md_branch_pages == 0 &&
|
||||||
|
txn->mt_geo.now < 1234) ||
|
||||||
|
/* Не суетимся если страница в зоне включенного упреждающего чтения */
|
||||||
|
(readahead_enabled && pgno + num < readahead_edge))
|
||||||
|
env->me_prefault_write = false;
|
||||||
|
}
|
||||||
|
|
||||||
retry_gc_refresh_oldest:;
|
retry_gc_refresh_oldest:;
|
||||||
txnid_t oldest = txn_oldest_reader(txn);
|
txnid_t oldest = txn_oldest_reader(txn);
|
||||||
retry_gc_have_oldest:
|
retry_gc_have_oldest:
|
||||||
@ -12359,7 +12380,8 @@ static int sync_locked(MDBX_env *env, unsigned flags, MDBX_meta *const pending,
|
|||||||
mode_bits |= MDBX_SYNC_SIZE;
|
mode_bits |= MDBX_SYNC_SIZE;
|
||||||
if (flags & MDBX_NOMETASYNC)
|
if (flags & MDBX_NOMETASYNC)
|
||||||
mode_bits |= MDBX_SYNC_IODQ;
|
mode_bits |= MDBX_SYNC_IODQ;
|
||||||
}
|
} else if (unlikely(env->me_incore))
|
||||||
|
goto skip_incore_sync;
|
||||||
if (!MDBX_AVOID_MSYNC && (flags & MDBX_WRITEMAP)) {
|
if (!MDBX_AVOID_MSYNC && (flags & MDBX_WRITEMAP)) {
|
||||||
#if MDBX_ENABLE_PGOP_STAT
|
#if MDBX_ENABLE_PGOP_STAT
|
||||||
env->me_lck->mti_pgop_stat.msync.weak += sync_op;
|
env->me_lck->mti_pgop_stat.msync.weak += sync_op;
|
||||||
@ -12391,6 +12413,7 @@ static int sync_locked(MDBX_env *env, unsigned flags, MDBX_meta *const pending,
|
|||||||
atomic_store64(&env->me_lck->mti_unsynced_pages, 0, mo_Relaxed);
|
atomic_store64(&env->me_lck->mti_unsynced_pages, 0, mo_Relaxed);
|
||||||
} else {
|
} else {
|
||||||
assert(rc == MDBX_RESULT_TRUE /* carry non-steady */);
|
assert(rc == MDBX_RESULT_TRUE /* carry non-steady */);
|
||||||
|
skip_incore_sync:
|
||||||
eASSERT(env, env->me_lck->mti_unsynced_pages.weak > 0);
|
eASSERT(env, env->me_lck->mti_unsynced_pages.weak > 0);
|
||||||
eASSERT(env, env->me_lck->mti_eoos_timestamp.weak != 0);
|
eASSERT(env, env->me_lck->mti_eoos_timestamp.weak != 0);
|
||||||
unaligned_poke_u64(4, pending->mm_sign, MDBX_DATASIGN_WEAK);
|
unaligned_poke_u64(4, pending->mm_sign, MDBX_DATASIGN_WEAK);
|
||||||
@ -12495,14 +12518,15 @@ static int sync_locked(MDBX_env *env, unsigned flags, MDBX_meta *const pending,
|
|||||||
memcpy(target->mm_sign, pending->mm_sign, 8);
|
memcpy(target->mm_sign, pending->mm_sign, 8);
|
||||||
osal_flush_incoherent_cpu_writeback();
|
osal_flush_incoherent_cpu_writeback();
|
||||||
jitter4testing(true);
|
jitter4testing(true);
|
||||||
|
if (!env->me_incore) {
|
||||||
if (!MDBX_AVOID_MSYNC) {
|
if (!MDBX_AVOID_MSYNC) {
|
||||||
/* sync meta-pages */
|
/* sync meta-pages */
|
||||||
#if MDBX_ENABLE_PGOP_STAT
|
#if MDBX_ENABLE_PGOP_STAT
|
||||||
env->me_lck->mti_pgop_stat.msync.weak += 1;
|
env->me_lck->mti_pgop_stat.msync.weak += 1;
|
||||||
#endif /* MDBX_ENABLE_PGOP_STAT */
|
#endif /* MDBX_ENABLE_PGOP_STAT */
|
||||||
rc = osal_msync(&env->me_dxb_mmap, 0, pgno_align2os_bytes(env, NUM_METAS),
|
rc = osal_msync(
|
||||||
(flags & MDBX_NOMETASYNC)
|
&env->me_dxb_mmap, 0, pgno_align2os_bytes(env, NUM_METAS),
|
||||||
? MDBX_SYNC_KICK
|
(flags & MDBX_NOMETASYNC) ? MDBX_SYNC_KICK
|
||||||
: MDBX_SYNC_DATA | MDBX_SYNC_IODQ);
|
: MDBX_SYNC_DATA | MDBX_SYNC_IODQ);
|
||||||
} else {
|
} else {
|
||||||
#if MDBX_ENABLE_PGOP_STAT
|
#if MDBX_ENABLE_PGOP_STAT
|
||||||
@ -12512,7 +12536,8 @@ static int sync_locked(MDBX_env *env, unsigned flags, MDBX_meta *const pending,
|
|||||||
rc = osal_pwrite(env->me_fd4meta, page, env->me_psize,
|
rc = osal_pwrite(env->me_fd4meta, page, env->me_psize,
|
||||||
ptr_dist(page, env->me_map));
|
ptr_dist(page, env->me_map));
|
||||||
if (likely(rc == MDBX_SUCCESS)) {
|
if (likely(rc == MDBX_SUCCESS)) {
|
||||||
osal_flush_incoherent_mmap(target, sizeof(MDBX_meta), env->me_os_psize);
|
osal_flush_incoherent_mmap(target, sizeof(MDBX_meta),
|
||||||
|
env->me_os_psize);
|
||||||
if ((flags & MDBX_NOMETASYNC) == 0 &&
|
if ((flags & MDBX_NOMETASYNC) == 0 &&
|
||||||
env->me_fd4meta == env->me_lazy_fd) {
|
env->me_fd4meta == env->me_lazy_fd) {
|
||||||
#if MDBX_ENABLE_PGOP_STAT
|
#if MDBX_ENABLE_PGOP_STAT
|
||||||
@ -12524,6 +12549,7 @@ static int sync_locked(MDBX_env *env, unsigned flags, MDBX_meta *const pending,
|
|||||||
}
|
}
|
||||||
if (unlikely(rc != MDBX_SUCCESS))
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
#if MDBX_ENABLE_PGOP_STAT
|
#if MDBX_ENABLE_PGOP_STAT
|
||||||
env->me_lck->mti_pgop_stat.wops.weak += 1;
|
env->me_lck->mti_pgop_stat.wops.weak += 1;
|
||||||
@ -12542,7 +12568,8 @@ static int sync_locked(MDBX_env *env, unsigned flags, MDBX_meta *const pending,
|
|||||||
}
|
}
|
||||||
osal_flush_incoherent_mmap(target, sizeof(MDBX_meta), env->me_os_psize);
|
osal_flush_incoherent_mmap(target, sizeof(MDBX_meta), env->me_os_psize);
|
||||||
/* sync meta-pages */
|
/* sync meta-pages */
|
||||||
if ((flags & MDBX_NOMETASYNC) == 0 && env->me_fd4meta == env->me_lazy_fd) {
|
if ((flags & MDBX_NOMETASYNC) == 0 && env->me_fd4meta == env->me_lazy_fd &&
|
||||||
|
!env->me_incore) {
|
||||||
#if MDBX_ENABLE_PGOP_STAT
|
#if MDBX_ENABLE_PGOP_STAT
|
||||||
env->me_lck->mti_pgop_stat.fsync.weak += 1;
|
env->me_lck->mti_pgop_stat.fsync.weak += 1;
|
||||||
#endif /* MDBX_ENABLE_PGOP_STAT */
|
#endif /* MDBX_ENABLE_PGOP_STAT */
|
||||||
@ -13050,8 +13077,7 @@ mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t size_now,
|
|||||||
pgno2bytes(env, pv2pages(pages2pv(bytes2pgno(env, growth_step))));
|
pgno2bytes(env, pv2pages(pages2pv(bytes2pgno(env, growth_step))));
|
||||||
env->me_dbgeo.shrink =
|
env->me_dbgeo.shrink =
|
||||||
pgno2bytes(env, pv2pages(pages2pv(bytes2pgno(env, shrink_threshold))));
|
pgno2bytes(env, pv2pages(pages2pv(bytes2pgno(env, shrink_threshold))));
|
||||||
if (!env->me_options.flags.non_auto.rp_augment_limit)
|
adjust_defaults(env);
|
||||||
env->me_options.rp_augment_limit = default_rp_augment_limit(env);
|
|
||||||
|
|
||||||
ENSURE(env, env->me_dbgeo.lower >= MIN_MAPSIZE);
|
ENSURE(env, env->me_dbgeo.lower >= MIN_MAPSIZE);
|
||||||
ENSURE(env, env->me_dbgeo.lower / (unsigned)pagesize >= MIN_PAGENO);
|
ENSURE(env, env->me_dbgeo.lower / (unsigned)pagesize >= MIN_PAGENO);
|
||||||
@ -14017,8 +14043,8 @@ static uint32_t merge_sync_flags(const uint32_t a, const uint32_t b) {
|
|||||||
!F_ISSET(r, MDBX_UTTERLY_NOSYNC))
|
!F_ISSET(r, MDBX_UTTERLY_NOSYNC))
|
||||||
r = (r - MDBX_DEPRECATED_MAPASYNC) | MDBX_SAFE_NOSYNC;
|
r = (r - MDBX_DEPRECATED_MAPASYNC) | MDBX_SAFE_NOSYNC;
|
||||||
|
|
||||||
/* force MDBX_NOMETASYNC if MDBX_SAFE_NOSYNC enabled */
|
/* force MDBX_NOMETASYNC if NOSYNC enabled */
|
||||||
if (r & MDBX_SAFE_NOSYNC)
|
if (r & (MDBX_SAFE_NOSYNC | MDBX_UTTERLY_NOSYNC))
|
||||||
r |= MDBX_NOMETASYNC;
|
r |= MDBX_NOMETASYNC;
|
||||||
|
|
||||||
assert(!(F_ISSET(r, MDBX_UTTERLY_NOSYNC) &&
|
assert(!(F_ISSET(r, MDBX_UTTERLY_NOSYNC) &&
|
||||||
@ -14746,6 +14772,16 @@ __cold int mdbx_env_openW(MDBX_env *env, const wchar_t *pathname,
|
|||||||
goto bailout;
|
goto bailout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = osal_check_fs_incore(env->me_lazy_fd);
|
||||||
|
env->me_incore = false;
|
||||||
|
if (rc == MDBX_RESULT_TRUE) {
|
||||||
|
env->me_incore = true;
|
||||||
|
NOTICE("%s", "in-core database");
|
||||||
|
} else if (unlikely(rc != MDBX_SUCCESS)) {
|
||||||
|
ERROR("check_fs_incore(), err %d", rc);
|
||||||
|
goto bailout;
|
||||||
|
}
|
||||||
|
|
||||||
if (unlikely(/* recovery mode */ env->me_stuck_meta >= 0) &&
|
if (unlikely(/* recovery mode */ env->me_stuck_meta >= 0) &&
|
||||||
(lck_rc != /* exclusive */ MDBX_RESULT_TRUE ||
|
(lck_rc != /* exclusive */ MDBX_RESULT_TRUE ||
|
||||||
(flags & MDBX_EXCLUSIVE) == 0)) {
|
(flags & MDBX_EXCLUSIVE) == 0)) {
|
||||||
@ -14784,8 +14820,6 @@ __cold int mdbx_env_openW(MDBX_env *env, const wchar_t *pathname,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & MDBX_RDONLY) == 0) {
|
if ((flags & MDBX_RDONLY) == 0) {
|
||||||
if (!env->me_options.flags.non_auto.rp_augment_limit)
|
|
||||||
env->me_options.rp_augment_limit = default_rp_augment_limit(env);
|
|
||||||
const size_t tsize = sizeof(MDBX_txn) + sizeof(MDBX_cursor),
|
const size_t tsize = sizeof(MDBX_txn) + sizeof(MDBX_cursor),
|
||||||
size = tsize + env->me_maxdbs *
|
size = tsize + env->me_maxdbs *
|
||||||
(sizeof(MDBX_db) + sizeof(MDBX_cursor *) +
|
(sizeof(MDBX_db) + sizeof(MDBX_cursor *) +
|
||||||
@ -14821,6 +14855,8 @@ __cold int mdbx_env_openW(MDBX_env *env, const wchar_t *pathname,
|
|||||||
ior_direct, env->me_overlapped_fd
|
ior_direct, env->me_overlapped_fd
|
||||||
#endif /* Windows */
|
#endif /* Windows */
|
||||||
);
|
);
|
||||||
|
if (rc == MDBX_SUCCESS)
|
||||||
|
adjust_defaults(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MDBX_DEBUG
|
#if MDBX_DEBUG
|
||||||
|
@ -1273,12 +1273,14 @@ struct MDBX_env {
|
|||||||
#if !(defined(_WIN32) || defined(_WIN64))
|
#if !(defined(_WIN32) || defined(_WIN64))
|
||||||
unsigned writethrough_threshold;
|
unsigned writethrough_threshold;
|
||||||
#endif /* Windows */
|
#endif /* Windows */
|
||||||
|
bool prefault_write;
|
||||||
union {
|
union {
|
||||||
unsigned all;
|
unsigned all;
|
||||||
/* tracks options with non-auto values but tuned by user */
|
/* tracks options with non-auto values but tuned by user */
|
||||||
struct {
|
struct {
|
||||||
unsigned dp_limit : 1;
|
unsigned dp_limit : 1;
|
||||||
unsigned rp_augment_limit : 1;
|
unsigned rp_augment_limit : 1;
|
||||||
|
unsigned prefault_write : 1;
|
||||||
} non_auto;
|
} non_auto;
|
||||||
} flags;
|
} flags;
|
||||||
} me_options;
|
} me_options;
|
||||||
@ -1300,6 +1302,7 @@ struct MDBX_env {
|
|||||||
int semid;
|
int semid;
|
||||||
} me_sysv_ipc;
|
} me_sysv_ipc;
|
||||||
#endif /* MDBX_LOCKING == MDBX_LOCKING_SYSV */
|
#endif /* MDBX_LOCKING == MDBX_LOCKING_SYSV */
|
||||||
|
bool me_incore;
|
||||||
|
|
||||||
MDBX_env *me_lcklist_next;
|
MDBX_env *me_lcklist_next;
|
||||||
|
|
||||||
@ -1308,6 +1311,7 @@ struct MDBX_env {
|
|||||||
MDBX_txn *me_txn; /* current write transaction */
|
MDBX_txn *me_txn; /* current write transaction */
|
||||||
osal_fastmutex_t me_dbi_lock;
|
osal_fastmutex_t me_dbi_lock;
|
||||||
MDBX_dbi me_numdbs; /* number of DBs opened */
|
MDBX_dbi me_numdbs; /* number of DBs opened */
|
||||||
|
bool me_prefault_write;
|
||||||
|
|
||||||
MDBX_page *me_dp_reserve; /* list of malloc'ed blocks for re-use */
|
MDBX_page *me_dp_reserve; /* list of malloc'ed blocks for re-use */
|
||||||
unsigned me_dp_reserve_len;
|
unsigned me_dp_reserve_len;
|
||||||
|
44
src/osal.c
44
src/osal.c
@ -1760,6 +1760,50 @@ MDBX_INTERNAL_FUNC int osal_check_fs_rdonly(mdbx_filehandle_t handle,
|
|||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MDBX_INTERNAL_FUNC int osal_check_fs_incore(mdbx_filehandle_t handle) {
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
(void)handle;
|
||||||
|
#else
|
||||||
|
struct statfs statfs_info;
|
||||||
|
if (fstatfs(handle, &statfs_info))
|
||||||
|
return errno;
|
||||||
|
|
||||||
|
#if defined(__OpenBSD__)
|
||||||
|
const unsigned type = 0;
|
||||||
|
#else
|
||||||
|
const unsigned type = statfs_info.f_type;
|
||||||
|
#endif
|
||||||
|
switch (type) {
|
||||||
|
case 0x28cd3d45 /* CRAMFS_MAGIC */:
|
||||||
|
case 0x858458f6 /* RAMFS_MAGIC */:
|
||||||
|
case 0x01021994 /* TMPFS_MAGIC */:
|
||||||
|
case 0x73717368 /* SQUASHFS_MAGIC */:
|
||||||
|
case 0x7275 /* ROMFS_MAGIC */:
|
||||||
|
return MDBX_RESULT_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \
|
||||||
|
defined(__BSD__) || defined(__bsdi__) || defined(__DragonFly__) || \
|
||||||
|
defined(__APPLE__) || defined(__MACH__) || defined(MFSNAMELEN) || \
|
||||||
|
defined(MFSTYPENAMELEN) || defined(VFS_NAMELEN)
|
||||||
|
const char *const name = statfs_info.f_fstypename;
|
||||||
|
const size_t name_len = sizeof(statfs_info.f_fstypename);
|
||||||
|
#else
|
||||||
|
const char *const name = "";
|
||||||
|
const size_t name_len = 0;
|
||||||
|
#endif
|
||||||
|
if (name_len) {
|
||||||
|
if (strncasecmp("tmpfs", name, 6) == 0 ||
|
||||||
|
strncasecmp("mfs", name, 4) == 0 ||
|
||||||
|
strncasecmp("ramfs", name, 6) == 0 ||
|
||||||
|
strncasecmp("romfs", name, 6) == 0)
|
||||||
|
return MDBX_RESULT_TRUE;
|
||||||
|
}
|
||||||
|
#endif /* !Windows */
|
||||||
|
|
||||||
|
return MDBX_RESULT_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static int osal_check_fs_local(mdbx_filehandle_t handle, int flags) {
|
static int osal_check_fs_local(mdbx_filehandle_t handle, int flags) {
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
if (mdbx_RunningUnderWine() && !(flags & MDBX_EXCLUSIVE))
|
if (mdbx_RunningUnderWine() && !(flags & MDBX_EXCLUSIVE))
|
||||||
|
@ -585,6 +585,7 @@ MDBX_INTERNAL_FUNC int osal_msync(const osal_mmap_t *map, size_t offset,
|
|||||||
MDBX_INTERNAL_FUNC int osal_check_fs_rdonly(mdbx_filehandle_t handle,
|
MDBX_INTERNAL_FUNC int osal_check_fs_rdonly(mdbx_filehandle_t handle,
|
||||||
const pathchar_t *pathname,
|
const pathchar_t *pathname,
|
||||||
int err);
|
int err);
|
||||||
|
MDBX_INTERNAL_FUNC int osal_check_fs_incore(mdbx_filehandle_t handle);
|
||||||
|
|
||||||
MDBX_MAYBE_UNUSED static __inline uint32_t osal_getpid(void) {
|
MDBX_MAYBE_UNUSED static __inline uint32_t osal_getpid(void) {
|
||||||
STATIC_ASSERT(sizeof(mdbx_pid_t) <= sizeof(uint32_t));
|
STATIC_ASSERT(sizeof(mdbx_pid_t) <= sizeof(uint32_t));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user