mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-04 18:44:13 +08:00
mdbx: purpose-oriented openfile().
Change-Id: I657689dab538af9a27c27f58eeb4e5ca43bdbc38
This commit is contained in:
parent
116d14bb76
commit
2db5736554
@ -8597,8 +8597,7 @@ static int __cold mdbx_setup_lck(MDBX_env *env, char *lck_pathname,
|
|||||||
mdbx_assert(env, env->me_fd != INVALID_HANDLE_VALUE);
|
mdbx_assert(env, env->me_fd != INVALID_HANDLE_VALUE);
|
||||||
mdbx_assert(env, env->me_lfd == INVALID_HANDLE_VALUE);
|
mdbx_assert(env, env->me_lfd == INVALID_HANDLE_VALUE);
|
||||||
|
|
||||||
int err = mdbx_openfile(lck_pathname, O_RDWR | O_CREAT, mode, &env->me_lfd,
|
int err = mdbx_openfile(MDBX_OPEN_LCK, env, lck_pathname, &env->me_lfd, mode);
|
||||||
(env->me_flags & MDBX_EXCLUSIVE) ? true : false);
|
|
||||||
if (err != MDBX_SUCCESS) {
|
if (err != MDBX_SUCCESS) {
|
||||||
if (!(err == MDBX_ENOFILE && (env->me_flags & MDBX_EXCLUSIVE)) &&
|
if (!(err == MDBX_ENOFILE && (env->me_flags & MDBX_EXCLUSIVE)) &&
|
||||||
!((err == MDBX_EROFS || err == MDBX_EACCESS || err == MDBX_EPERM) &&
|
!((err == MDBX_EROFS || err == MDBX_EACCESS || err == MDBX_EPERM) &&
|
||||||
@ -8908,9 +8907,9 @@ __cold int mdbx_is_readahead_reasonable(size_t volume, intptr_t redundancy) {
|
|||||||
#error "Persistent DB flags & env flags overlap, but both go in mm_flags"
|
#error "Persistent DB flags & env flags overlap, but both go in mm_flags"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int __cold mdbx_env_open(MDBX_env *env, const char *path, unsigned flags,
|
int __cold mdbx_env_open(MDBX_env *env, const char *pathname, unsigned flags,
|
||||||
mode_t mode) {
|
mode_t mode) {
|
||||||
if (unlikely(!env || !path))
|
if (unlikely(!env || !pathname))
|
||||||
return MDBX_EINVAL;
|
return MDBX_EINVAL;
|
||||||
|
|
||||||
if (unlikely(env->me_signature != MDBX_ME_SIGNATURE))
|
if (unlikely(env->me_signature != MDBX_ME_SIGNATURE))
|
||||||
@ -8923,7 +8922,7 @@ int __cold mdbx_env_open(MDBX_env *env, const char *path, unsigned flags,
|
|||||||
(env->me_flags & MDBX_ENV_ACTIVE) != 0)
|
(env->me_flags & MDBX_ENV_ACTIVE) != 0)
|
||||||
return MDBX_EPERM;
|
return MDBX_EPERM;
|
||||||
|
|
||||||
size_t len_full, len = strlen(path);
|
size_t len_full, len = strlen(pathname);
|
||||||
if (flags & MDBX_NOSUBDIR) {
|
if (flags & MDBX_NOSUBDIR) {
|
||||||
len_full = len + sizeof(MDBX_LOCK_SUFFIX) + len + 1;
|
len_full = len + sizeof(MDBX_LOCK_SUFFIX) + len + 1;
|
||||||
} else {
|
} else {
|
||||||
@ -8936,12 +8935,12 @@ int __cold mdbx_env_open(MDBX_env *env, const char *path, unsigned flags,
|
|||||||
char *dxb_pathname;
|
char *dxb_pathname;
|
||||||
if (flags & MDBX_NOSUBDIR) {
|
if (flags & MDBX_NOSUBDIR) {
|
||||||
dxb_pathname = lck_pathname + len + sizeof(MDBX_LOCK_SUFFIX);
|
dxb_pathname = lck_pathname + len + sizeof(MDBX_LOCK_SUFFIX);
|
||||||
sprintf(lck_pathname, "%s" MDBX_LOCK_SUFFIX, path);
|
sprintf(lck_pathname, "%s" MDBX_LOCK_SUFFIX, pathname);
|
||||||
strcpy(dxb_pathname, path);
|
strcpy(dxb_pathname, pathname);
|
||||||
} else {
|
} else {
|
||||||
dxb_pathname = lck_pathname + len + sizeof(MDBX_LOCKNAME);
|
dxb_pathname = lck_pathname + len + sizeof(MDBX_LOCKNAME);
|
||||||
sprintf(lck_pathname, "%s" MDBX_LOCKNAME, path);
|
sprintf(lck_pathname, "%s" MDBX_LOCKNAME, pathname);
|
||||||
sprintf(dxb_pathname, "%s" MDBX_DATANAME, path);
|
sprintf(dxb_pathname, "%s" MDBX_DATANAME, pathname);
|
||||||
}
|
}
|
||||||
|
|
||||||
int rc = MDBX_SUCCESS;
|
int rc = MDBX_SUCCESS;
|
||||||
@ -8978,7 +8977,7 @@ int __cold mdbx_env_open(MDBX_env *env, const char *path, unsigned flags,
|
|||||||
if (rc)
|
if (rc)
|
||||||
goto bailout;
|
goto bailout;
|
||||||
|
|
||||||
env->me_path = mdbx_strdup(path);
|
env->me_path = mdbx_strdup(pathname);
|
||||||
env->me_dbxs = mdbx_calloc(env->me_maxdbs, sizeof(MDBX_dbx));
|
env->me_dbxs = mdbx_calloc(env->me_maxdbs, sizeof(MDBX_dbx));
|
||||||
env->me_dbflags = mdbx_calloc(env->me_maxdbs, sizeof(env->me_dbflags[0]));
|
env->me_dbflags = mdbx_calloc(env->me_maxdbs, sizeof(env->me_dbflags[0]));
|
||||||
env->me_dbiseqs = mdbx_calloc(env->me_maxdbs, sizeof(env->me_dbiseqs[0]));
|
env->me_dbiseqs = mdbx_calloc(env->me_maxdbs, sizeof(env->me_dbiseqs[0]));
|
||||||
@ -8989,37 +8988,39 @@ int __cold mdbx_env_open(MDBX_env *env, const char *path, unsigned flags,
|
|||||||
env->me_dbxs[FREE_DBI].md_cmp =
|
env->me_dbxs[FREE_DBI].md_cmp =
|
||||||
mdbx_cmp_int_align4; /* aligned MDBX_INTEGERKEY */
|
mdbx_cmp_int_align4; /* aligned MDBX_INTEGERKEY */
|
||||||
|
|
||||||
int oflags;
|
if ((flags & (MDBX_RDONLY | MDBX_NOSUBDIR)) == 0 && mode != 0) {
|
||||||
if (F_ISSET(flags, MDBX_RDONLY))
|
|
||||||
oflags = O_RDONLY;
|
|
||||||
else if (mode != 0) {
|
|
||||||
if ((flags & MDBX_NOSUBDIR) == 0) {
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
if (!CreateDirectoryA(path, nullptr)) {
|
const size_t wlen = mbstowcs(nullptr, pathname, INT_MAX);
|
||||||
rc = GetLastError();
|
if (wlen < 1 || wlen > /* MAX_PATH */ INT16_MAX)
|
||||||
if (rc != ERROR_ALREADY_EXISTS)
|
return ERROR_INVALID_NAME;
|
||||||
goto bailout;
|
wchar_t *const pathnameW = _alloca((wlen + 1) * sizeof(wchar_t));
|
||||||
}
|
if (wlen != mbstowcs(pathnameW, pathname, wlen + 1)) {
|
||||||
#else
|
rc = ERROR_INVALID_NAME;
|
||||||
const mode_t dir_mode =
|
goto bailout;
|
||||||
(/* inherit read/write permissions for group and others */ mode &
|
|
||||||
(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) |
|
|
||||||
/* always add read/write/search for owner */ S_IRWXU |
|
|
||||||
((mode & S_IRGRP) ? /* +search if readable by group */ S_IXGRP : 0) |
|
|
||||||
((mode & S_IROTH) ? /* +search if readable by others */ S_IXOTH : 0);
|
|
||||||
if (mkdir(path, dir_mode)) {
|
|
||||||
rc = errno;
|
|
||||||
if (rc != EEXIST)
|
|
||||||
goto bailout;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
oflags = O_RDWR | O_CREAT;
|
if (!CreateDirectoryW(pathnameW, nullptr)) {
|
||||||
} else
|
rc = GetLastError();
|
||||||
oflags = O_RDWR;
|
if (rc != ERROR_ALREADY_EXISTS)
|
||||||
|
goto bailout;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
const mode_t dir_mode =
|
||||||
|
(/* inherit read/write permissions for group and others */ mode &
|
||||||
|
(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) |
|
||||||
|
/* always add read/write/search for owner */ S_IRWXU |
|
||||||
|
((mode & S_IRGRP) ? /* +search if readable by group */ S_IXGRP : 0) |
|
||||||
|
((mode & S_IROTH) ? /* +search if readable by others */ S_IXOTH : 0);
|
||||||
|
if (mkdir(pathname, dir_mode)) {
|
||||||
|
rc = errno;
|
||||||
|
if (rc != EEXIST)
|
||||||
|
goto bailout;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
rc = mdbx_openfile(dxb_pathname, oflags, mode, &env->me_fd,
|
rc = mdbx_openfile(F_ISSET(flags, MDBX_RDONLY) ? MDBX_OPEN_DXB_READ
|
||||||
(env->me_flags & MDBX_EXCLUSIVE) ? true : false);
|
: MDBX_OPEN_DXB_LAZY,
|
||||||
|
env, dxb_pathname, &env->me_fd, mode);
|
||||||
if (rc != MDBX_SUCCESS)
|
if (rc != MDBX_SUCCESS)
|
||||||
goto bailout;
|
goto bailout;
|
||||||
|
|
||||||
@ -14443,49 +14444,28 @@ int __cold mdbx_env_copy(MDBX_env *env, const char *dest_path, unsigned flags) {
|
|||||||
if (unlikely(env->me_signature != MDBX_ME_SIGNATURE))
|
if (unlikely(env->me_signature != MDBX_ME_SIGNATURE))
|
||||||
return MDBX_EBADSIGN;
|
return MDBX_EBADSIGN;
|
||||||
|
|
||||||
char *dxb_pathname;
|
|
||||||
mdbx_filehandle_t newfd = INVALID_HANDLE_VALUE;
|
|
||||||
|
|
||||||
if (env->me_flags & MDBX_NOSUBDIR) {
|
|
||||||
dxb_pathname = (char *)dest_path;
|
|
||||||
} else {
|
|
||||||
size_t len = strlen(dest_path);
|
|
||||||
len += sizeof(MDBX_DATANAME);
|
|
||||||
dxb_pathname = mdbx_malloc(len);
|
|
||||||
if (!dxb_pathname)
|
|
||||||
return MDBX_ENOMEM;
|
|
||||||
sprintf(dxb_pathname, "%s" MDBX_DATANAME, dest_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The destination path must exist, but the destination file must not.
|
/* The destination path must exist, but the destination file must not.
|
||||||
* We don't want the OS to cache the writes, since the source data is
|
* We don't want the OS to cache the writes, since the source data is
|
||||||
* already in the OS cache. */
|
* already in the OS cache. */
|
||||||
int rc = mdbx_openfile(dxb_pathname, O_WRONLY | O_CREAT | O_EXCL, 0640,
|
mdbx_filehandle_t newfd;
|
||||||
&newfd, true);
|
int rc = mdbx_openfile(MDBX_OPEN_COPY, env, dest_path, &newfd,
|
||||||
if (rc == MDBX_SUCCESS) {
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
if (env->me_psize >= env->me_os_psize) {
|
(mode_t)-1
|
||||||
#ifdef F_NOCACHE /* __APPLE__ */
|
#else
|
||||||
(void)fcntl(newfd, F_NOCACHE, 1);
|
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP
|
||||||
#elif defined(O_DIRECT) && defined(F_GETFL)
|
|
||||||
/* Set O_DIRECT if the file system supports it */
|
|
||||||
if ((rc = fcntl(newfd, F_GETFL)) != -1)
|
|
||||||
(void)fcntl(newfd, F_SETFL, rc | O_DIRECT);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
);
|
||||||
|
if (rc == MDBX_SUCCESS)
|
||||||
rc = mdbx_env_copy2fd(env, newfd, flags);
|
rc = mdbx_env_copy2fd(env, newfd, flags);
|
||||||
}
|
|
||||||
|
|
||||||
if (newfd != INVALID_HANDLE_VALUE) {
|
if (newfd != INVALID_HANDLE_VALUE) {
|
||||||
int err = mdbx_closefile(newfd);
|
int err = mdbx_closefile(newfd);
|
||||||
if (rc == MDBX_SUCCESS && err != rc)
|
if (rc == MDBX_SUCCESS && err != rc)
|
||||||
rc = err;
|
rc = err;
|
||||||
if (rc != MDBX_SUCCESS)
|
if (rc != MDBX_SUCCESS)
|
||||||
(void)mdbx_removefile(dxb_pathname);
|
(void)mdbx_removefile(dest_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dxb_pathname != dest_path)
|
|
||||||
mdbx_free(dxb_pathname);
|
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,106 +512,156 @@ MDBX_INTERNAL_FUNC int mdbx_fastmutex_release(mdbx_fastmutex_t *fastmutex) {
|
|||||||
|
|
||||||
MDBX_INTERNAL_FUNC int mdbx_removefile(const char *pathname) {
|
MDBX_INTERNAL_FUNC int mdbx_removefile(const char *pathname) {
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
return DeleteFileA(pathname) ? MDBX_SUCCESS : GetLastError();
|
const size_t wlen = mbstowcs(nullptr, pathname, INT_MAX);
|
||||||
|
if (wlen < 1 || wlen > /* MAX_PATH */ INT16_MAX)
|
||||||
|
return ERROR_INVALID_NAME;
|
||||||
|
wchar_t *const pathnameW = _alloca((wlen + 1) * sizeof(wchar_t));
|
||||||
|
if (wlen != mbstowcs(pathnameW, pathname, wlen + 1))
|
||||||
|
return ERROR_INVALID_NAME;
|
||||||
|
return DeleteFileW(pathnameW) ? MDBX_SUCCESS : GetLastError();
|
||||||
#else
|
#else
|
||||||
return unlink(pathname) ? errno : MDBX_SUCCESS;
|
return unlink(pathname) ? errno : MDBX_SUCCESS;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
MDBX_INTERNAL_FUNC int mdbx_openfile(const char *pathname, int flags,
|
MDBX_INTERNAL_FUNC int mdbx_openfile(const enum mdbx_openfile_purpose purpose,
|
||||||
mode_t mode, mdbx_filehandle_t *fd,
|
const MDBX_env *env, const char *pathname,
|
||||||
bool exclusive) {
|
mdbx_filehandle_t *fd,
|
||||||
|
mode_t unix_mode_bits) {
|
||||||
*fd = INVALID_HANDLE_VALUE;
|
*fd = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
(void)mode;
|
const size_t wlen = mbstowcs(nullptr, pathname, INT_MAX);
|
||||||
size_t wlen = mbstowcs(nullptr, pathname, INT_MAX);
|
|
||||||
if (wlen < 1 || wlen > /* MAX_PATH */ INT16_MAX)
|
if (wlen < 1 || wlen > /* MAX_PATH */ INT16_MAX)
|
||||||
return ERROR_INVALID_NAME;
|
return ERROR_INVALID_NAME;
|
||||||
wchar_t *const pathnameW = _alloca((wlen + 1) * sizeof(wchar_t));
|
wchar_t *const pathnameW = _alloca((wlen + 1) * sizeof(wchar_t));
|
||||||
if (wlen != mbstowcs(pathnameW, pathname, wlen + 1))
|
if (wlen != mbstowcs(pathnameW, pathname, wlen + 1))
|
||||||
return ERROR_INVALID_NAME;
|
return ERROR_INVALID_NAME;
|
||||||
|
|
||||||
DWORD DesiredAccess, ShareMode;
|
DWORD CreationDisposition = unix_mode_bits ? OPEN_ALWAYS : OPEN_EXISTING;
|
||||||
DWORD FlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
|
DWORD FlagsAndAttributes =
|
||||||
switch (flags & (O_RDONLY | O_WRONLY | O_RDWR)) {
|
FILE_FLAG_POSIX_SEMANTICS | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
|
||||||
|
DWORD DesiredAccess = FILE_READ_ATTRIBUTES;
|
||||||
|
DWORD ShareMode = (env->me_flags & MDBX_EXCLUSIVE)
|
||||||
|
? 0
|
||||||
|
: (FILE_SHARE_READ | FILE_SHARE_WRITE);
|
||||||
|
|
||||||
|
switch (purpose) {
|
||||||
default:
|
default:
|
||||||
return ERROR_INVALID_PARAMETER;
|
return ERROR_INVALID_PARAMETER;
|
||||||
case O_RDONLY:
|
case MDBX_OPEN_LCK:
|
||||||
DesiredAccess = GENERIC_READ;
|
CreationDisposition = OPEN_ALWAYS;
|
||||||
ShareMode =
|
DesiredAccess |= GENERIC_READ | GENERIC_WRITE;
|
||||||
exclusive ? FILE_SHARE_READ : (FILE_SHARE_READ | FILE_SHARE_WRITE);
|
FlagsAndAttributes |= FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_TEMPORARY;
|
||||||
break;
|
break;
|
||||||
case O_WRONLY: /* assume for MDBX_env_copy() and friends output */
|
case MDBX_OPEN_DXB_READ:
|
||||||
DesiredAccess = GENERIC_WRITE;
|
CreationDisposition = OPEN_EXISTING;
|
||||||
ShareMode = 0;
|
DesiredAccess |= GENERIC_READ;
|
||||||
|
ShareMode |= FILE_SHARE_READ;
|
||||||
|
break;
|
||||||
|
case MDBX_OPEN_DXB_LAZY:
|
||||||
|
DesiredAccess |= GENERIC_READ | GENERIC_WRITE;
|
||||||
|
break;
|
||||||
|
case MDBX_OPEN_DXB_DSYNC:
|
||||||
|
CreationDisposition = OPEN_EXISTING;
|
||||||
|
DesiredAccess |= GENERIC_WRITE;
|
||||||
FlagsAndAttributes |= FILE_FLAG_WRITE_THROUGH;
|
FlagsAndAttributes |= FILE_FLAG_WRITE_THROUGH;
|
||||||
break;
|
break;
|
||||||
case O_RDWR:
|
case MDBX_OPEN_COPY:
|
||||||
DesiredAccess = GENERIC_READ | GENERIC_WRITE;
|
|
||||||
ShareMode = exclusive ? 0 : (FILE_SHARE_READ | FILE_SHARE_WRITE);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD CreationDisposition;
|
|
||||||
switch (flags & (O_EXCL | O_CREAT)) {
|
|
||||||
default:
|
|
||||||
return ERROR_INVALID_PARAMETER;
|
|
||||||
case 0:
|
|
||||||
CreationDisposition = OPEN_EXISTING;
|
|
||||||
break;
|
|
||||||
case O_EXCL | O_CREAT:
|
|
||||||
CreationDisposition = CREATE_NEW;
|
CreationDisposition = CREATE_NEW;
|
||||||
FlagsAndAttributes |= FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
|
ShareMode = 0;
|
||||||
break;
|
DesiredAccess |= GENERIC_WRITE;
|
||||||
case O_CREAT:
|
FlagsAndAttributes |=
|
||||||
CreationDisposition = OPEN_ALWAYS;
|
(env->me_psize < env->me_os_psize) ? 0 : FILE_FLAG_NO_BUFFERING;
|
||||||
FlagsAndAttributes |= FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
*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 GetLastError();
|
return GetLastError();
|
||||||
if ((flags & O_CREAT) && GetLastError() != ERROR_ALREADY_EXISTS) {
|
|
||||||
/* set FILE_ATTRIBUTE_NOT_CONTENT_INDEXED for new file */
|
BY_HANDLE_FILE_INFORMATION info;
|
||||||
DWORD FileAttributes = GetFileAttributesA(pathname);
|
if (!GetFileInformationByHandle(*fd, &info)) {
|
||||||
if (FileAttributes == INVALID_FILE_ATTRIBUTES ||
|
int err = GetLastError();
|
||||||
!SetFileAttributesA(pathname, FileAttributes |
|
CloseHandle(*fd);
|
||||||
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED)) {
|
*fd = INVALID_HANDLE_VALUE;
|
||||||
int rc = GetLastError();
|
return err;
|
||||||
CloseHandle(*fd);
|
|
||||||
*fd = INVALID_HANDLE_VALUE;
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
const DWORD AttributesDiff =
|
||||||
|
(info.dwFileAttributes ^ FlagsAndAttributes) &
|
||||||
|
(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED |
|
||||||
|
FILE_ATTRIBUTE_TEMPORARY | FILE_ATTRIBUTE_COMPRESSED);
|
||||||
|
if (AttributesDiff)
|
||||||
|
(void)SetFileAttributesW(pathnameW, info.dwFileAttributes ^ AttributesDiff);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
(void)exclusive;
|
int flags = unix_mode_bits ? O_CREAT : 0;
|
||||||
|
switch (purpose) {
|
||||||
|
default:
|
||||||
|
return EINVAL;
|
||||||
|
case MDBX_OPEN_LCK:
|
||||||
|
flags |= O_RDWR;
|
||||||
|
break;
|
||||||
|
case MDBX_OPEN_DXB_READ:
|
||||||
|
flags = O_RDONLY;
|
||||||
|
break;
|
||||||
|
case MDBX_OPEN_DXB_LAZY:
|
||||||
|
flags |= O_RDWR;
|
||||||
|
break;
|
||||||
|
case MDBX_OPEN_COPY:
|
||||||
|
flags = O_CREAT | O_WRONLY | O_EXCL;
|
||||||
|
break;
|
||||||
|
case MDBX_OPEN_DXB_DSYNC:
|
||||||
|
flags |= O_WRONLY;
|
||||||
|
#if defined(O_DSYNC)
|
||||||
|
flags |= O_DSYNC;
|
||||||
|
#elif defined(O_SYNC)
|
||||||
|
flags |= O_SYNC;
|
||||||
|
#elif defined(O_FSYNC)
|
||||||
|
flags |= O_FSYNC;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool direct_nocache_for_copy =
|
||||||
|
env->me_psize >= env->me_os_psize && purpose == MDBX_OPEN_COPY;
|
||||||
|
if (direct_nocache_for_copy) {
|
||||||
|
#if defined(O_DIRECT)
|
||||||
|
flags |= O_DIRECT;
|
||||||
|
#endif /* O_DIRECT */
|
||||||
|
#if defined(O_NOCACHE)
|
||||||
|
flags |= O_NOCACHE;
|
||||||
|
#endif /* O_NOCACHE */
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef O_CLOEXEC
|
#ifdef O_CLOEXEC
|
||||||
flags |= O_CLOEXEC;
|
flags |= O_CLOEXEC;
|
||||||
#endif /* O_CLOEXEC */
|
#endif /* O_CLOEXEC */
|
||||||
*fd = open(pathname, flags, mode);
|
|
||||||
|
*fd = open(pathname, flags, unix_mode_bits);
|
||||||
|
#if defined(O_DIRECT)
|
||||||
|
if (*fd < 0 && (flags & O_DIRECT) &&
|
||||||
|
(errno == EINVAL || errno == EAFNOSUPPORT)) {
|
||||||
|
flags &= ~(O_DIRECT | O_EXCL);
|
||||||
|
*fd = open(pathname, flags, unix_mode_bits);
|
||||||
|
}
|
||||||
|
#endif /* O_DIRECT */
|
||||||
if (*fd < 0)
|
if (*fd < 0)
|
||||||
return errno;
|
return errno;
|
||||||
|
|
||||||
#if defined(FD_CLOEXEC) && !defined(O_CLOEXEC)
|
#if defined(FD_CLOEXEC) && !defined(O_CLOEXEC)
|
||||||
int fd_flags = fcntl(*fd, F_GETFD);
|
const int fd_flags = fcntl(*fd, F_GETFD);
|
||||||
if (fd_flags != -1)
|
if (fd_flags != -1)
|
||||||
(void)fcntl(*fd, F_SETFD, fd_flags | FD_CLOEXEC);
|
(void)fcntl(*fd, F_SETFD, fd_flags | FD_CLOEXEC);
|
||||||
#endif /* FD_CLOEXEC && !O_CLOEXEC */
|
#endif /* FD_CLOEXEC && !O_CLOEXEC */
|
||||||
|
|
||||||
if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_WRONLY) {
|
if (direct_nocache_for_copy) {
|
||||||
/* assume for MDBX_env_copy() and friends output */
|
#if defined(F_NOCACHE) && !defined(O_NOCACHE)
|
||||||
#if defined(O_DIRECT)
|
|
||||||
int fd_flags = fcntl(*fd, F_GETFD);
|
|
||||||
if (fd_flags != -1)
|
|
||||||
(void)fcntl(*fd, F_SETFL, fd_flags | O_DIRECT);
|
|
||||||
#endif /* O_DIRECT */
|
|
||||||
#if defined(F_NOCACHE)
|
|
||||||
(void)fcntl(*fd, F_NOCACHE, 1);
|
(void)fcntl(*fd, F_NOCACHE, 1);
|
||||||
#endif /* F_NOCACHE */
|
#endif /* F_NOCACHE */
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
|
@ -566,9 +566,19 @@ MDBX_INTERNAL_FUNC int mdbx_filesync(mdbx_filehandle_t fd,
|
|||||||
MDBX_INTERNAL_FUNC int mdbx_ftruncate(mdbx_filehandle_t fd, uint64_t length);
|
MDBX_INTERNAL_FUNC int mdbx_ftruncate(mdbx_filehandle_t fd, uint64_t length);
|
||||||
MDBX_INTERNAL_FUNC int mdbx_fseek(mdbx_filehandle_t fd, uint64_t pos);
|
MDBX_INTERNAL_FUNC int mdbx_fseek(mdbx_filehandle_t fd, uint64_t pos);
|
||||||
MDBX_INTERNAL_FUNC int mdbx_filesize(mdbx_filehandle_t fd, uint64_t *length);
|
MDBX_INTERNAL_FUNC int mdbx_filesize(mdbx_filehandle_t fd, uint64_t *length);
|
||||||
MDBX_INTERNAL_FUNC int mdbx_openfile(const char *pathname, int flags,
|
|
||||||
mode_t mode, mdbx_filehandle_t *fd,
|
enum mdbx_openfile_purpose {
|
||||||
bool exclusive);
|
MDBX_OPEN_DXB_READ = 0,
|
||||||
|
MDBX_OPEN_DXB_LAZY = 1,
|
||||||
|
MDBX_OPEN_DXB_DSYNC = 2,
|
||||||
|
MDBX_OPEN_LCK = 3,
|
||||||
|
MDBX_OPEN_COPY = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
MDBX_INTERNAL_FUNC int mdbx_openfile(const enum mdbx_openfile_purpose purpose,
|
||||||
|
const MDBX_env *env, const char *pathname,
|
||||||
|
mdbx_filehandle_t *fd,
|
||||||
|
mode_t unix_mode_bits);
|
||||||
MDBX_INTERNAL_FUNC int mdbx_closefile(mdbx_filehandle_t fd);
|
MDBX_INTERNAL_FUNC int mdbx_closefile(mdbx_filehandle_t fd);
|
||||||
MDBX_INTERNAL_FUNC int mdbx_removefile(const char *pathname);
|
MDBX_INTERNAL_FUNC int mdbx_removefile(const char *pathname);
|
||||||
MDBX_INTERNAL_FUNC int mdbx_is_pipe(mdbx_filehandle_t fd);
|
MDBX_INTERNAL_FUNC int mdbx_is_pipe(mdbx_filehandle_t fd);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user