Для Windows tr_sys_path_rename
может использовать флаг MOVEFILE_COPY_ALLOWED
вместо собственного встроенного цикла «чтение и копирование» из util.c:tr_moveFile
Тогда версия для Linux могла бы использовать более современные copy_file_range
вместо перебора каждого из них.
возможно что-то вроде этого:
size_t tr_sys_file_copy(tr_sys_file_t infile, tr_sys_file_t outfile, size_t len, tr_error** error )
{
TR_ASSERT(outfile != NULL);
TR_ASSERT(infile != NULL);
bool ret = false;
unsigned int flags = 0;
size_t res;
res = copy_file_range(infile, NULL, outfile, NULL, &len, flags);
if (res) {
return res;
}
else {
set_system_error(error, errno);
return res;
}
}
А может быть:
tr_sys_file_copy_fallback(tr_sys_file_t infile, tr_sys_file_t outfile, size_t len, tr_error** error ) {
TR_ASSERT(outfile != NULL);
TR_ASSERT(infile != NULL);
uint64_t bytesLeft = len;
size_t const buflen = 1024 * 128; /* 128 KiB buffer */
tr_sys_path_info info;
while (bytesLeft > 0)
{
uint64_t const bytesThisPass = MIN(bytesLeft, buflen);
uint64_t numRead;
uint64_t bytesWritten;
if (!tr_sys_file_read(infile, buf, bytesThisPass, &numRead, error))
{
break;
}
if (!tr_sys_file_write(outfile, buf, numRead, &bytesWritten, error))
{
break;
}
TR_ASSERT(numRead == bytesWritten);
TR_ASSERT(bytesWritten <= bytesLeft);
bytesLeft -= bytesWritten;
}
return bytesLeft;
}
Тогда версия для Linux могла бы использовать более современный copy_file_range вместо перебора каждого из них.
Это невозможно сделать одним вызовом (или простым циклом):
If file_in is a sparse file, then copy_file_range() may expand any
holes existing in the requested range. Users may benefit from calling
copy_file_range() in a loop, and using the lseek(2) SEEK_DATA and
SEEK_HOLE operations to find the locations of data segments.
(человек copy_file_range)
В идеале мы должны обеспечить правильную блокировку и использовать sendfile () в отдельном потоке.
Это почти то же самое, что и текущий код "перемещения файла", когда
rename
не работает. Это тоже не оставляет разреженных разделов, поэтому я не
Считайте, что проблема при его замене.
В воскресенье, 14 июля 2019 г., в 22:41 andreygursky [email protected] написал:
>
Тогда версия для Linux могла бы использовать более современный copy_file_range вместо перебора каждого из них.
Это невозможно сделать одним вызовом (или простым циклом):
If file_in is a sparse file, then copy_file_range() may expand any holes existing in the requested range. Users may benefit from calling copy_file_range() in a loop, and using the lseek(2) SEEK_DATA and SEEK_HOLE operations to find the locations of data segments.
(человек copy_file_range)
В идеале мы должны обеспечить правильную блокировку и использовать sendfile () в отдельном потоке.
-
Вы получаете это, потому что вы являетесь автором темы.
Ответьте на это письмо напрямую, просмотрите его на GitHub или отключите обсуждение.
Текущий «файл перемещения» связан как ссылка
Текущая функция:
https://github.com/transmission/transmission/blob/master/libtransmission/utils.c#L1682
https://github.com/transmission/transmission/blob/master/libtransmission/utils.c#L1744
Это тоже не оставляет разреженных разделов, поэтому я не
Считайте, что проблема при его замене.
И в нем отсутствует предварительное выделение для обычных файлов.
Ага. Это тоже. Текущего плохого поведения «переместить файл» достаточно, чтобы вызвать абсурдную нагрузку в некоторых настройках. Если возможно, кажется, что альтернативное решение в glibc copy_file_range также является лучшей реализацией.
Я поигрался с этим. Трудно сделать правильный подход к кроссплатформенности: похоже, не существует какого-либо интерфейса POSIX для копии в ядре. Но я думаю, что для каждой операционной системы стоит специальный корпус, потому что по мере того, как файловые системы становятся более эффективными при копировании, мы хотим получить доступ к этим функциям автоматически.
У меня есть базовая реализация, работающая на MacOSX и FreeBSD, но мне нужно настроить еще несколько систем для ее тестирования.
Я думаю, что эта работа ортогональна асинхронному перемещению файла. Одно не должно мешать другому. Для волонтерских проектов сокращение масштабов - враг продуктивности.
Изменения здесь: https://github.com/transmission/transmission/compare/master...RobCrowston : kernelcopy-wip
Вкратце, я создаю новую абстракцию под названием tr_sys_path_copy (). (Я пошел с копией вместо перемещения, потому что, когда мы делаем это асинхронной операцией, может потребоваться сохранить исходный файл в течение некоторого неопределенного периода времени после завершения копирования, чтобы закрыть дескрипторы файлов в других потоках.)
Сегодня я скомпилировал и запустил новый тест (тестовая копия передачи) на MacOS 10.15.1, Windows Server 2016, Linux 5.0 (Ubuntu 19.05), Linux 5.3 (Arch 2019-12-03), FreeBSD 12.1. (использует резервное пространство пользователя) и FreeBSD 13. В каждом случае я проверял с помощью отладчика, что мы выполняем соответствующие системные вызовы. К сожалению, мне не удалось получить код для сборки на OpenBSD 6.5, NetBSD 8.1 или Solaris 10 из-за некоторых несвязанных проблем с libevent, но я не уверен, что эти платформы больше поддерживают libtransmission. В любом случае это изменение не должно повлиять на эти платформы.
Еще предстоит сделать:
Обратная связь приветствуется.
+1 к асинхронному перемещению данных. Перемещение больших торрентов между файловыми системами блокирует все приложение .
Самый полезный комментарий
+1 к асинхронному перемещению данных. Перемещение больших торрентов между файловыми системами блокирует все приложение .