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
18
src/core.c
18
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);
|
||||
if (err != MDBX_SUCCESS) {
|
||||
if (!(err == MDBX_ENOFILE && (env->me_flags & MDBX_EXCLUSIVE)) &&
|
||||
!((err == MDBX_EROFS || err == MDBX_EACCESS || err == MDBX_EPERM) &&
|
||||
(env->me_flags & MDBX_RDONLY)))
|
||||
switch (err) {
|
||||
default:
|
||||
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;
|
||||
}
|
||||
|
||||
if (err != MDBX_ENOFILE) {
|
||||
/* ensure the file system is read-only */
|
||||
err = mdbx_check_fs_rdonly(env->me_lazy_fd, lck_pathname, err);
|
||||
if (err != MDBX_SUCCESS &&
|
||||
/* ignore ERROR_NOT_SUPPORTED for exclusive mode */
|
||||
!(err == MDBX_ENOSYS && (env->me_flags & MDBX_EXCLUSIVE)))
|
||||
return err;
|
||||
}
|
||||
|
||||
/* LY: without-lck mode (e.g. exclusive or on read-only filesystem) */
|
||||
/* 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,
|
||||
CreationDisposition, FlagsAndAttributes, NULL);
|
||||
if (*fd == INVALID_HANDLE_VALUE)
|
||||
return (int)GetLastError();
|
||||
if (*fd == INVALID_HANDLE_VALUE) {
|
||||
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;
|
||||
if (!GetFileInformationByHandle(*fd, &info)) {
|
||||
@ -706,6 +713,12 @@ MDBX_INTERNAL_FUNC int mdbx_openfile(const enum mdbx_openfile_purpose purpose,
|
||||
}
|
||||
#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 */
|
||||
#if STDIN_FILENO == 0 && STDOUT_FILENO == 1 && STDERR_FILENO == 2
|
||||
if (*fd == STDIN_FILENO) {
|
||||
@ -1091,10 +1104,10 @@ MDBX_INTERNAL_FUNC int mdbx_check_fs_rdonly(mdbx_filehandle_t handle,
|
||||
#else
|
||||
struct statvfs info;
|
||||
if (err != MDBX_ENOFILE) {
|
||||
if (statvfs(pathname, &info))
|
||||
return errno;
|
||||
if ((info.f_flag & ST_RDONLY) == 0)
|
||||
if (statvfs(pathname, &info) == 0 && (info.f_flag & ST_RDONLY) == 0)
|
||||
return err;
|
||||
if (errno != MDBX_ENOFILE)
|
||||
return errno;
|
||||
}
|
||||
if (fstatvfs(handle, &info))
|
||||
return errno;
|
||||
|
Loading…
Reference in New Issue
Block a user