mirror of
https://github.com/isar/libmdbx.git
synced 2024-10-30 11:29:19 +08:00
mdbx: initial mdbx_check_fs_rdonly() and mdbx_check_fs_local().
Change-Id: Iff48f1ad1ef54c1e51dceebce16097be030206bd
This commit is contained in:
parent
b7ed67543f
commit
647d832556
2
mdbx.h
2
mdbx.h
@ -555,6 +555,7 @@ typedef DWORD mdbx_tid_t;
|
||||
#define MDBX_EPERM ERROR_INVALID_FUNCTION
|
||||
#define MDBX_EINTR ERROR_CANCELLED
|
||||
#define MDBX_ENOFILE ERROR_FILE_NOT_FOUND
|
||||
#define MDBX_EREMOTE ERROR_REMOTE_STORAGE_MEDIA_ERROR
|
||||
|
||||
#else
|
||||
|
||||
@ -580,6 +581,7 @@ typedef pthread_t mdbx_tid_t;
|
||||
#define MDBX_EPERM EPERM
|
||||
#define MDBX_EINTR EINTR
|
||||
#define MDBX_ENOFILE ENOENT
|
||||
#define MDBX_EREMOTE ENOTBLK
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1499,8 +1499,7 @@ static MDBX_PNL mdbx_pnl_alloc(size_t size) {
|
||||
size_t bytes = pnl2bytes(size);
|
||||
MDBX_PNL pl = mdbx_malloc(bytes);
|
||||
if (likely(pl)) {
|
||||
#if __GLIBC_PREREQ(2, 12) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
|
||||
defined(malloc_usable_size)
|
||||
#if __GLIBC_PREREQ(2, 12) || defined(__FreeBSD__) || defined(malloc_usable_size)
|
||||
bytes = malloc_usable_size(pl);
|
||||
#endif /* malloc_usable_size */
|
||||
pl[0] = bytes2pnl(bytes);
|
||||
@ -1527,8 +1526,7 @@ static void mdbx_pnl_shrink(MDBX_PNL *ppl) {
|
||||
size_t bytes = pnl2bytes(MDBX_PNL_INITIAL);
|
||||
MDBX_PNL pl = mdbx_realloc(*ppl - 1, bytes);
|
||||
if (likely(pl)) {
|
||||
#if __GLIBC_PREREQ(2, 12) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
|
||||
defined(malloc_usable_size)
|
||||
#if __GLIBC_PREREQ(2, 12) || defined(__FreeBSD__) || defined(malloc_usable_size)
|
||||
bytes = malloc_usable_size(pl);
|
||||
#endif /* malloc_usable_size */
|
||||
*pl = bytes2pnl(bytes);
|
||||
@ -1554,8 +1552,7 @@ static int mdbx_pnl_reserve(MDBX_PNL *ppl, const size_t wanna) {
|
||||
size_t bytes = pnl2bytes(size);
|
||||
MDBX_PNL pl = mdbx_realloc(*ppl - 1, bytes);
|
||||
if (likely(pl)) {
|
||||
#if __GLIBC_PREREQ(2, 12) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
|
||||
defined(malloc_usable_size)
|
||||
#if __GLIBC_PREREQ(2, 12) || defined(__FreeBSD__) || defined(malloc_usable_size)
|
||||
bytes = malloc_usable_size(pl);
|
||||
#endif /* malloc_usable_size */
|
||||
*pl = bytes2pnl(bytes);
|
||||
@ -1767,8 +1764,7 @@ static MDBX_TXL mdbx_txl_alloc(void) {
|
||||
size_t bytes = txl2bytes(MDBX_TXL_INITIAL);
|
||||
MDBX_TXL tl = mdbx_malloc(bytes);
|
||||
if (likely(tl)) {
|
||||
#if __GLIBC_PREREQ(2, 12) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
|
||||
defined(malloc_usable_size)
|
||||
#if __GLIBC_PREREQ(2, 12) || defined(__FreeBSD__) || defined(malloc_usable_size)
|
||||
bytes = malloc_usable_size(tl);
|
||||
#endif /* malloc_usable_size */
|
||||
tl[0] = bytes2txl(bytes);
|
||||
@ -1800,8 +1796,7 @@ static int mdbx_txl_reserve(MDBX_TXL *ptl, const size_t wanna) {
|
||||
size_t bytes = txl2bytes(size);
|
||||
MDBX_TXL tl = mdbx_realloc(*ptl - 1, bytes);
|
||||
if (likely(tl)) {
|
||||
#if __GLIBC_PREREQ(2, 12) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
|
||||
defined(malloc_usable_size)
|
||||
#if __GLIBC_PREREQ(2, 12) || defined(__FreeBSD__) || defined(malloc_usable_size)
|
||||
bytes = malloc_usable_size(tl);
|
||||
#endif /* malloc_usable_size */
|
||||
*tl = bytes2txl(bytes);
|
||||
@ -8267,6 +8262,11 @@ static int __cold mdbx_setup_lck(MDBX_env *env, char *lck_pathname,
|
||||
(env->me_flags & MDBX_RDONLY)))
|
||||
return err;
|
||||
|
||||
/* ensure the file system is read-only */
|
||||
err = mdbx_check_fs_rdonly(env->me_fd, lck_pathname, err);
|
||||
if (err != MDBX_SUCCESS)
|
||||
return err;
|
||||
|
||||
/* LY: without-lck mode (e.g. exclusive or on read-only filesystem) */
|
||||
/* beginning of a locked section ---------------------------------------- */
|
||||
lcklist_lock();
|
||||
|
@ -179,8 +179,19 @@ __extern_C void __assert_rtn(const char *function, const char *file, int line,
|
||||
|
||||
#define __assert_fail(assertion, file, line, function) \
|
||||
__assert_rtn(function, file, line, assertion)
|
||||
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \
|
||||
defined(__BSD__) || defined(__NETBSD__) || defined(__bsdi__) || \
|
||||
#elif defined(__OpenBSD__)
|
||||
__extern_C __dead void __assert2(const char *file, int line,
|
||||
const char *function,
|
||||
const char *assertion) /* __nothrow */;
|
||||
#define __assert_fail(assertion, file, line, function) \
|
||||
__assert2(file, line, function, assertion)
|
||||
#elif defined(__NetBSD__)
|
||||
__extern_C __dead void __assert13(const char *file, int line,
|
||||
const char *function,
|
||||
const char *assertion) /* __nothrow */;
|
||||
#define __assert_fail(assertion, file, line, function) \
|
||||
__assert13(file, line, function, assertion)
|
||||
#elif defined(__FreeBSD__) || defined(__BSD__) || defined(__bsdi__) || \
|
||||
defined(__DragonFly__)
|
||||
__extern_C void __assert(const char *function, const char *file, int line,
|
||||
const char *assertion) /* __nothrow */
|
||||
@ -907,8 +918,36 @@ MDBX_INTERNAL_FUNC int mdbx_msync(mdbx_mmap_t *map, size_t offset,
|
||||
#endif
|
||||
}
|
||||
|
||||
MDBX_INTERNAL_FUNC int mdbx_check4nonlocal(mdbx_filehandle_t handle,
|
||||
int flags) {
|
||||
MDBX_INTERNAL_FUNC int mdbx_check_fs_rdonly(mdbx_filehandle_t handle,
|
||||
const char *pathname, int err) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
(void)pathname;
|
||||
(void)err;
|
||||
if (!mdbx_GetVolumeInformationByHandleW)
|
||||
return MDBX_ENOSYS;
|
||||
DWORD unused, flags;
|
||||
if (!mdbx_GetVolumeInformationByHandleW(handle, nullptr, 0, nullptr, &unused,
|
||||
&flags, nullptr, 0))
|
||||
return GetLastError();
|
||||
if ((flags & FILE_READ_ONLY_VOLUME) == 0)
|
||||
return MDBX_EACCESS;
|
||||
#else
|
||||
struct statvfs info;
|
||||
if (err != MDBX_ENOFILE) {
|
||||
if (statvfs(pathname, &info))
|
||||
return errno;
|
||||
if ((info.f_flag & ST_RDONLY) == 0)
|
||||
return err;
|
||||
}
|
||||
if (fstatvfs(handle, &info))
|
||||
return errno;
|
||||
if ((info.f_flag & ST_RDONLY) == 0)
|
||||
return (err == MDBX_ENOFILE) ? MDBX_EACCESS : err;
|
||||
#endif /* !Windows */
|
||||
return MDBX_SUCCESS;
|
||||
}
|
||||
|
||||
static int mdbx_check_fs_local(mdbx_filehandle_t handle, int flags) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
if (GetFileType(handle) != FILE_TYPE_DISK)
|
||||
return ERROR_FILE_OFFLINE;
|
||||
@ -1019,10 +1058,109 @@ MDBX_INTERNAL_FUNC int mdbx_check4nonlocal(mdbx_filehandle_t handle,
|
||||
return rc;
|
||||
}
|
||||
#else
|
||||
(void)handle;
|
||||
/* TODO: check for NFS handle ? */
|
||||
(void)flags;
|
||||
|
||||
struct statvfs statvfs_info;
|
||||
if (fstatvfs(handle, &statvfs_info))
|
||||
return errno;
|
||||
#if defined(ST_LOCAL) || defined(ST_EXPORTED)
|
||||
const unsigned long st_flags = statvfs_info.f_flag;
|
||||
#endif /* ST_LOCAL || ST_EXPORTED */
|
||||
|
||||
#if defined(__NetBSD__)
|
||||
const unsigned type = 0;
|
||||
const char *const name = statvfs_info.f_fstypename;
|
||||
const size_t name_len = VFS_NAMELEN;
|
||||
#elif defined(_AIX) || defined(__OS400__) || defined(FSTYPSZ) || \
|
||||
defined(_FSTYPSZ)
|
||||
const unsigned type = 0;
|
||||
const char *const name = statfs_info.f_basetype;
|
||||
const size_t name_len = sizeof(statfs_info.f_basetype);
|
||||
#elif defined(__sun) || defined(__SVR4) || defined(__svr4__) || \
|
||||
defined(ST_FSTYPSZ) || defined(_ST_FSTYPSZ)
|
||||
const unsigned type = 0;
|
||||
#if defined(_ST_FSTYPSZ) || defined(_ST_FSTYPSZ)
|
||||
struct stat stat_info;
|
||||
if (fstat(handle, &stat_info))
|
||||
return errno;
|
||||
const char *const name = stat_info.st_fstype;
|
||||
const size_t name_len = strlen(name);
|
||||
#else
|
||||
const char *const name = "";
|
||||
const size_t name_len = 0;
|
||||
#endif
|
||||
#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
|
||||
#if defined(MNT_LOCAL) || defined(MNT_EXPORTED)
|
||||
const unsigned long mnt_flags = statfs_info.f_flags;
|
||||
#endif /* MNT_LOCAL || MNT_EXPORTED */
|
||||
#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 unsigned name_len = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (name_len) {
|
||||
if (((name_len > 2 && strncasecmp("nfs", name, 3) == 0) ||
|
||||
strncasecmp("cifs", name, name_len) == 0 ||
|
||||
strncasecmp("ncpfs", name, name_len) == 0 ||
|
||||
strncasecmp("smbfs", name, name_len) == 0 ||
|
||||
((name_len > 3 && strncasecmp("fuse", name, 4) == 0) &&
|
||||
strncasecmp("fuseblk", name, name_len) != 0)) &&
|
||||
!(flags & MDBX_EXCLUSIVE))
|
||||
return MDBX_EREMOTE;
|
||||
if (strcasecmp("ftp", name) == 0 || strcasecmp("http", name) == 0 ||
|
||||
strcasecmp("sshfs", name) == 0)
|
||||
return MDBX_EREMOTE;
|
||||
}
|
||||
|
||||
#ifdef ST_LOCAL
|
||||
if ((st_flags & ST_LOCAL) == 0 && !(flags & MDBX_EXCLUSIVE))
|
||||
return MDBX_EREMOTE;
|
||||
#elif defined(MNT_LOCAL)
|
||||
if ((mnt_flags & MNT_LOCAL) == 0 && !(flags & MDBX_EXCLUSIVE))
|
||||
return MDBX_EREMOTE;
|
||||
#endif /* ST/MNT_LOCAL */
|
||||
|
||||
#ifdef ST_EXPORTED
|
||||
if (st_flags & ST_EXPORTED)
|
||||
return MDBX_EREMOTE;
|
||||
#elif defined(MNT_EXPORTED)
|
||||
if (mnt_flags & MNT_EXPORTED)
|
||||
return MDBX_EREMOTE;
|
||||
#endif /* ST/MNT_EXPORTED */
|
||||
|
||||
switch (type) {
|
||||
case 0xFF534D42 /* CIFS_MAGIC_NUMBER */:
|
||||
case 0x6969 /* NFS_SUPER_MAGIC */:
|
||||
case 0x564c /* NCP_SUPER_MAGIC */:
|
||||
case 0x517B /* SMB_SUPER_MAGIC */:
|
||||
#if defined(__digital__) || defined(__osf__) || defined(__osf)
|
||||
case 0x0E /* Tru64 NFS */:
|
||||
#endif
|
||||
#ifdef ST_FST_NFS
|
||||
case ST_FST_NFS:
|
||||
#endif
|
||||
if ((flags & MDBX_EXCLUSIVE) == 0)
|
||||
return MDBX_EREMOTE;
|
||||
case 0:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif /* Unix */
|
||||
|
||||
return MDBX_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1038,7 +1176,7 @@ MDBX_INTERNAL_FUNC int mdbx_mmap(const int flags, mdbx_mmap_t *map,
|
||||
map->filesize = 0;
|
||||
#endif /* Windows */
|
||||
|
||||
int err = mdbx_check4nonlocal(map->fd, flags);
|
||||
int err = mdbx_check_fs_local(map->fd, flags);
|
||||
if (unlikely(err != MDBX_SUCCESS))
|
||||
return err;
|
||||
|
||||
@ -1607,10 +1745,10 @@ __cold MDBX_INTERNAL_FUNC bin128_t mdbx_osal_bootid(void) {
|
||||
const int fd =
|
||||
open("/proc/sys/kernel/random/boot_id", O_RDONLY | O_NOFOLLOW);
|
||||
if (fd != -1) {
|
||||
struct statvfs fs;
|
||||
struct statfs fs;
|
||||
char buf[42];
|
||||
const ssize_t len =
|
||||
(fstatvfs(fd, &fs) == 0 && fs.f_fsid == /* procfs */ 0x00009FA0)
|
||||
(fstatfs(fd, &fs) == 0 && fs.f_type == /* procfs */ 0x9FA0)
|
||||
? read(fd, buf, sizeof(buf))
|
||||
: -1;
|
||||
close(fd);
|
||||
|
@ -74,6 +74,7 @@
|
||||
defined(__BSD__) || defined(__NETBSD__) || defined(__bsdi__) || \
|
||||
defined(__DragonFly__) || defined(__APPLE__) || defined(__MACH__)
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/types.h>
|
||||
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
@ -95,7 +96,7 @@
|
||||
#endif
|
||||
#endif /* !xBSD */
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || __has_include(<malloc_np.h>)
|
||||
#if defined(__FreeBSD__) || __has_include(<malloc_np.h>)
|
||||
#include <malloc_np.h>
|
||||
#endif
|
||||
|
||||
@ -114,7 +115,7 @@
|
||||
#if defined(__linux__) || defined(__gnu_linux__)
|
||||
#include <linux/sysctl.h>
|
||||
#include <sys/sendfile.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/statfs.h>
|
||||
#endif /* Linux */
|
||||
|
||||
#ifndef _XOPEN_SOURCE
|
||||
@ -200,6 +201,7 @@ static inline void *mdbx_realloc(void *ptr, size_t bytes) {
|
||||
#include <sys/mman.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/uio.h>
|
||||
#include <unistd.h>
|
||||
typedef pthread_t mdbx_thread_t;
|
||||
@ -347,7 +349,7 @@ typedef pthread_mutex_t mdbx_fastmutex_t;
|
||||
#include <sys/endian.h>
|
||||
#include <sys/types.h>
|
||||
#elif defined(__bsdi__) || defined(__DragonFly__) || defined(__FreeBSD__) || \
|
||||
defined(__NETBSD__) || defined(__NetBSD__) || \
|
||||
defined(__NetBSD__) || \
|
||||
defined(HAVE_SYS_PARAM_H) || __has_include(<sys/param.h>)
|
||||
#include <sys/param.h>
|
||||
#endif /* OS */
|
||||
@ -664,7 +666,8 @@ mdbx_resume_threads_after_remap(mdbx_handle_array_t *array);
|
||||
#endif /* Windows */
|
||||
MDBX_INTERNAL_FUNC int mdbx_msync(mdbx_mmap_t *map, size_t offset,
|
||||
size_t length, int async);
|
||||
MDBX_INTERNAL_FUNC int mdbx_check4nonlocal(mdbx_filehandle_t handle, int flags);
|
||||
MDBX_INTERNAL_FUNC int mdbx_check_fs_rdonly(mdbx_filehandle_t handle,
|
||||
const char *pathname, int err);
|
||||
|
||||
static __maybe_unused __inline uint32_t mdbx_getpid(void) {
|
||||
STATIC_ASSERT(sizeof(mdbx_pid_t) <= sizeof(uint32_t));
|
||||
|
Loading…
Reference in New Issue
Block a user