From d1e67645a26ee0f16cd48957c164cd29878b558f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Sat, 4 Jun 2022 02:04:55 +0300 Subject: [PATCH] mdbx: refine handling `EACCESS` while trying create LCK-file on a read-only filesystem. --- src/core.c | 30 +++++++++++++++++++++--------- src/osal.c | 23 ++++++++++++++++++----- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/core.c b/src/core.c index 674c4c78..e691f6d6 100644 --- a/src/core.c +++ b/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; + } - /* 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; + 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 ---------------------------------------- */ diff --git a/src/osal.c b/src/osal.c index c4622c9b..5a4d32eb 100644 --- a/src/osal.c +++ b/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;