mirror of
https://github.com/isar/libmdbx.git
synced 2024-10-30 11:29:19 +08:00
mdbx: refine handling EACCESS
while trying create LCK-file on a read-only filesystem.
This commit is contained in:
parent
a4da10bc62
commit
d1e67645a2
30
src/core.c
30
src/core.c
@ -12440,17 +12440,29 @@ __cold static int mdbx_setup_lck(MDBX_env *env, char *lck_pathname,
|
|||||||
|
|
||||||
int err = mdbx_openfile(MDBX_OPEN_LCK, env, lck_pathname, &env->me_lfd, mode);
|
int err = mdbx_openfile(MDBX_OPEN_LCK, env, lck_pathname, &env->me_lfd, mode);
|
||||||
if (err != MDBX_SUCCESS) {
|
if (err != MDBX_SUCCESS) {
|
||||||
if (!(err == MDBX_ENOFILE && (env->me_flags & MDBX_EXCLUSIVE)) &&
|
switch (err) {
|
||||||
!((err == MDBX_EROFS || err == MDBX_EACCESS || err == MDBX_EPERM) &&
|
default:
|
||||||
(env->me_flags & MDBX_RDONLY)))
|
|
||||||
return err;
|
return err;
|
||||||
|
case MDBX_ENOFILE:
|
||||||
|
case MDBX_EACCESS:
|
||||||
|
case MDBX_EPERM:
|
||||||
|
if (!F_ISSET(env->me_flags, MDBX_RDONLY | MDBX_EXCLUSIVE))
|
||||||
|
return err;
|
||||||
|
break;
|
||||||
|
case MDBX_EROFS:
|
||||||
|
if ((env->me_flags & MDBX_RDONLY) == 0)
|
||||||
|
return err;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* ensure the file system is read-only */
|
if (err != MDBX_ENOFILE) {
|
||||||
err = mdbx_check_fs_rdonly(env->me_lazy_fd, lck_pathname, err);
|
/* ensure the file system is read-only */
|
||||||
if (err != MDBX_SUCCESS &&
|
err = mdbx_check_fs_rdonly(env->me_lazy_fd, lck_pathname, err);
|
||||||
/* ignore ERROR_NOT_SUPPORTED for exclusive mode */
|
if (err != MDBX_SUCCESS &&
|
||||||
!(err == MDBX_ENOSYS && (env->me_flags & MDBX_EXCLUSIVE)))
|
/* ignore ERROR_NOT_SUPPORTED for exclusive mode */
|
||||||
return err;
|
!(err == MDBX_ENOSYS && (env->me_flags & MDBX_EXCLUSIVE)))
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/* LY: without-lck mode (e.g. exclusive or on read-only filesystem) */
|
/* LY: without-lck mode (e.g. exclusive or on read-only filesystem) */
|
||||||
/* beginning of a locked section ---------------------------------------- */
|
/* beginning of a locked section ---------------------------------------- */
|
||||||
|
23
src/osal.c
23
src/osal.c
@ -610,8 +610,15 @@ MDBX_INTERNAL_FUNC int mdbx_openfile(const enum mdbx_openfile_purpose purpose,
|
|||||||
|
|
||||||
*fd = CreateFileW(pathnameW, DesiredAccess, ShareMode, NULL,
|
*fd = CreateFileW(pathnameW, DesiredAccess, ShareMode, NULL,
|
||||||
CreationDisposition, FlagsAndAttributes, NULL);
|
CreationDisposition, FlagsAndAttributes, NULL);
|
||||||
if (*fd == INVALID_HANDLE_VALUE)
|
if (*fd == INVALID_HANDLE_VALUE) {
|
||||||
return (int)GetLastError();
|
int err = (int)GetLastError();
|
||||||
|
if (err == ERROR_ACCESS_DENIED && purpose == MDBX_OPEN_LCK) {
|
||||||
|
if (GetFileAttributesW(pathnameW) == INVALID_FILE_ATTRIBUTES &&
|
||||||
|
GetLastError() == ERROR_FILE_NOT_FOUND)
|
||||||
|
err = ERROR_FILE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
BY_HANDLE_FILE_INFORMATION info;
|
BY_HANDLE_FILE_INFORMATION info;
|
||||||
if (!GetFileInformationByHandle(*fd, &info)) {
|
if (!GetFileInformationByHandle(*fd, &info)) {
|
||||||
@ -706,6 +713,12 @@ MDBX_INTERNAL_FUNC int mdbx_openfile(const enum mdbx_openfile_purpose purpose,
|
|||||||
}
|
}
|
||||||
#endif /* O_DIRECT */
|
#endif /* O_DIRECT */
|
||||||
|
|
||||||
|
if (*fd < 0 && errno == EACCES && purpose == MDBX_OPEN_LCK) {
|
||||||
|
struct stat unused;
|
||||||
|
if (stat(pathname, &unused) == 0 || errno != ENOENT)
|
||||||
|
errno = EACCES /* restore errno if file exists */;
|
||||||
|
}
|
||||||
|
|
||||||
/* Safeguard for todo4recovery://erased_by_github/libmdbx/issues/144 */
|
/* Safeguard for todo4recovery://erased_by_github/libmdbx/issues/144 */
|
||||||
#if STDIN_FILENO == 0 && STDOUT_FILENO == 1 && STDERR_FILENO == 2
|
#if STDIN_FILENO == 0 && STDOUT_FILENO == 1 && STDERR_FILENO == 2
|
||||||
if (*fd == STDIN_FILENO) {
|
if (*fd == STDIN_FILENO) {
|
||||||
@ -1091,10 +1104,10 @@ MDBX_INTERNAL_FUNC int mdbx_check_fs_rdonly(mdbx_filehandle_t handle,
|
|||||||
#else
|
#else
|
||||||
struct statvfs info;
|
struct statvfs info;
|
||||||
if (err != MDBX_ENOFILE) {
|
if (err != MDBX_ENOFILE) {
|
||||||
if (statvfs(pathname, &info))
|
if (statvfs(pathname, &info) == 0 && (info.f_flag & ST_RDONLY) == 0)
|
||||||
return errno;
|
|
||||||
if ((info.f_flag & ST_RDONLY) == 0)
|
|
||||||
return err;
|
return err;
|
||||||
|
if (errno != MDBX_ENOFILE)
|
||||||
|
return errno;
|
||||||
}
|
}
|
||||||
if (fstatvfs(handle, &info))
|
if (fstatvfs(handle, &info))
|
||||||
return errno;
|
return errno;
|
||||||
|
Loading…
Reference in New Issue
Block a user