From 8833dc6871abd15e999c34b96c9e007cc72f4acd 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, 22 Oct 2022 01:38:33 +0300 Subject: [PATCH] =?UTF-8?q?mdbx:=20=D0=BA=D0=BE=D1=81=D1=82=D1=8B=D0=BB?= =?UTF-8?q?=D1=8C=20=D0=B4=D0=BB=D1=8F=20=D0=BE=D0=B1=D1=85=D0=BE=D0=B4?= =?UTF-8?q?=D0=B0=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BE=D0=BA=20encryptfs.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Выяснилось что утилита `mdbx_copy` и функции `mdbx_env_copy()` могут создавать ПРОБЛЕМЫ если целевой файл расположен в encryptfs (такая файловая система в Linux). При этом может быть четыре исхода в зависимости от версии ядра и положения звезд на небе: - всё хорошо; - плохие данные в копии без возврата ошибок; - ошибка EINVAL(22) при копировании; - oops или зависание ядра, отвал смонтированной encryptfs и т.п. В текущем понимании, причина обусловлена ошибой в коде fs, которая проявляется при использовании системного вызова `copy_file_range`. --- src/core.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/core.c b/src/core.c index 3e7ebd23..1723a9ad 100644 --- a/src/core.c +++ b/src/core.c @@ -20339,6 +20339,11 @@ __cold static int env_copy_asis(MDBX_env *env, MDBX_txn *read_txn, #if MDBX_USE_COPYFILERANGE static bool copyfilerange_unavailable; bool not_the_same_filesystem = false; + struct statfs statfs_info; + if (fstatfs(fd, &statfs_info) || + statfs_info.f_type == /* ECRYPTFS_SUPER_MAGIC */ 0xf15f) + /* avoid use copyfilerange_unavailable() to ecryptfs due bugs */ + not_the_same_filesystem = true; #endif /* MDBX_USE_COPYFILERANGE */ for (size_t offset = meta_bytes; rc == MDBX_SUCCESS && offset < used_size;) { #if MDBX_USE_SENDFILE @@ -20372,7 +20377,9 @@ __cold static int env_copy_asis(MDBX_env *env, MDBX_txn *read_txn, if (bytes_copied == 0) break; rc = errno; - if (rc == EXDEV) + if (rc == EXDEV || rc == /* workaround for ecryptfs bug(s), + maybe usefull for others fs */ + EINVAL) not_the_same_filesystem = true; else if (ignore_enosys(rc) == MDBX_RESULT_TRUE) copyfilerange_unavailable = true;