mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-04 18:14:12 +08:00
mdbx: fix unexpected EXDEV
(Cross-device link) error from mdbx_env_copy()
Fallback to `write()` if `copy_file_range()` syscall returns `EXDEV`.
This commit is contained in:
parent
c25df39cd0
commit
7a06cac680
1
.github/actions/spelling/expect.txt
vendored
1
.github/actions/spelling/expect.txt
vendored
@ -482,6 +482,7 @@ Exa
|
|||||||
exactkey
|
exactkey
|
||||||
exactp
|
exactp
|
||||||
excpt
|
excpt
|
||||||
|
EXDEV
|
||||||
exe
|
exe
|
||||||
executables
|
executables
|
||||||
exename
|
exename
|
||||||
|
18
src/core.c
18
src/core.c
@ -19120,6 +19120,10 @@ __cold static int mdbx_env_copy_asis(MDBX_env *env, MDBX_txn *read_txn,
|
|||||||
|
|
||||||
uint8_t *const data_buffer =
|
uint8_t *const data_buffer =
|
||||||
buffer + ceil_powerof2(meta_bytes, env->me_os_psize);
|
buffer + ceil_powerof2(meta_bytes, env->me_os_psize);
|
||||||
|
#if MDBX_USE_COPYFILERANGE
|
||||||
|
static bool copyfilerange_unavailable;
|
||||||
|
bool not_the_same_filesystem = false;
|
||||||
|
#endif /* MDBX_USE_COPYFILERANGE */
|
||||||
for (size_t offset = meta_bytes; rc == MDBX_SUCCESS && offset < used_size;) {
|
for (size_t offset = meta_bytes; rc == MDBX_SUCCESS && offset < used_size;) {
|
||||||
#if MDBX_USE_SENDFILE
|
#if MDBX_USE_SENDFILE
|
||||||
static bool sendfile_unavailable;
|
static bool sendfile_unavailable;
|
||||||
@ -19139,8 +19143,8 @@ __cold static int mdbx_env_copy_asis(MDBX_env *env, MDBX_txn *read_txn,
|
|||||||
#endif /* MDBX_USE_SENDFILE */
|
#endif /* MDBX_USE_SENDFILE */
|
||||||
|
|
||||||
#if MDBX_USE_COPYFILERANGE
|
#if MDBX_USE_COPYFILERANGE
|
||||||
static bool copyfilerange_unavailable;
|
if (!dest_is_pipe && !not_the_same_filesystem &&
|
||||||
if (!dest_is_pipe && likely(!copyfilerange_unavailable)) {
|
likely(!copyfilerange_unavailable)) {
|
||||||
off_t in_offset = offset, out_offset = offset;
|
off_t in_offset = offset, out_offset = offset;
|
||||||
ssize_t bytes_copied = copy_file_range(
|
ssize_t bytes_copied = copy_file_range(
|
||||||
env->me_lazy_fd, &in_offset, fd, &out_offset, used_size - offset, 0);
|
env->me_lazy_fd, &in_offset, fd, &out_offset, used_size - offset, 0);
|
||||||
@ -19149,9 +19153,15 @@ __cold static int mdbx_env_copy_asis(MDBX_env *env, MDBX_txn *read_txn,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
rc = MDBX_ENODATA;
|
rc = MDBX_ENODATA;
|
||||||
if (bytes_copied == 0 || ignore_enosys(rc = errno) != MDBX_RESULT_TRUE)
|
if (bytes_copied == 0)
|
||||||
|
break;
|
||||||
|
rc = errno;
|
||||||
|
if (rc == EXDEV)
|
||||||
|
not_the_same_filesystem = true;
|
||||||
|
else if (ignore_enosys(rc) == MDBX_RESULT_TRUE)
|
||||||
|
copyfilerange_unavailable = true;
|
||||||
|
else
|
||||||
break;
|
break;
|
||||||
copyfilerange_unavailable = true;
|
|
||||||
}
|
}
|
||||||
#endif /* MDBX_USE_COPYFILERANGE */
|
#endif /* MDBX_USE_COPYFILERANGE */
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user