Transmission: [улучшение] Будьте умнее при перемещении файлов

Созданный на 14 июл. 2019  ·  8Комментарии  ·  Источник: transmission/transmission

Для 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;
}
core enhancement pr welcome

Самый полезный комментарий

+1 к асинхронному перемещению данных. Перемещение больших торрентов между файловыми системами блокирует все приложение .

Все 8 Комментарий

Тогда версия для 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. В любом случае это изменение не должно повлиять на эти платформы.

Еще предстоит сделать:

  • Протестируйте на более старом ядре Windows. Для этого необходимо настроить среду разработки виртуальной машины.
  • Протестируйте межтомное копирование (раз уж это то, о чем мы заботимся). Не знаю, как это сделать в автоматическом режиме.
  • Тестовый файл tr_sys_path_copy () для достаточно большого файла (> 100 ГБ). Наверное, нельзя сделать в автоматическом режиме.
  • Тестируйте на месте, а не просто тестируйте tr_sys_path_copy () изолированно.
  • Замените на время один из моих бит-торрент-серверов этим кодом, посмотрите, как он себя ведет в реальном мире.

Обратная связь приветствуется.

+1 к асинхронному перемещению данных. Перемещение больших торрентов между файловыми системами блокирует все приложение .

Была ли эта страница полезной?
0 / 5 - 0 рейтинги