Transmission: [mejora] Sea más inteligente al mover archivos

Creado en 14 jul. 2019  ·  8Comentarios  ·  Fuente: transmission/transmission

Para Windows, tr_sys_path_rename podría usar la bandera MOVEFILE_COPY_ALLOWED lugar de su propio bucle integrado de "lectura y copia" de util.c:tr_moveFile

Entonces, la versión de Linux podría usar el copy_file_range más moderno en lugar de recorrer cada uno.

tal vez algo como esto:

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;
        }
}

Y tal vez un:

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

Comentario más útil

+1 para hacer que los movimientos de datos sean asincrónicos. Mover grandes torrents entre sistemas de archivos bloquea toda la aplicación .

Todos 8 comentarios

Entonces, la versión de Linux podría usar el copy_file_range más moderno en lugar de recorrer cada uno.

Esto no se puede hacer solo con una llamada (o en un bucle simple):

       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.

(hombre copy_file_range)

Idealmente, deberíamos asegurarnos de que los bloqueos sean adecuados y usar sendfile () en un hilo separado.

Es prácticamente lo mismo que el código actual de "mover archivo" cuando
rename falla. Eso tampoco mantiene secciones dispersas, así que no
considérelo un problema a la hora de sustituirlo.

El domingo, 14 de julio de 2019 a las 10:41 p.m., andreygursky [email protected] escribió:
>

Entonces, la versión de Linux podría usar el copy_file_range más moderno en lugar de recorrer cada uno.

Esto no se puede hacer solo con una llamada (o en un bucle simple):

   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.

(hombre copy_file_range)

Idealmente, deberíamos asegurarnos de que los bloqueos sean adecuados y usar sendfile () en un hilo separado.

-
Estás recibiendo esto porque eres el autor del hilo.
Responda a este correo electrónico directamente, véalo en GitHub o silencia el hilo.

Eso tampoco mantiene secciones dispersas, así que no
considérelo un problema a la hora de sustituirlo.

Y falta preasignación para archivos normales.

Sí. Eso también. El mal comportamiento actual de "mover archivo" es suficiente para causar cargas absurdas en algunas configuraciones. Si es posible, parece que la solución alternativa en glibc copy_file_range también es una mejor implementación.

He jugado con esto. Es difícil hacerlo bien en una forma multiplataforma: no parece haber ninguna interfaz POSIX para una copia en el kernel. Pero creo que vale la pena usar una carcasa especial para cada sistema operativo porque a medida que los sistemas de archivos se vuelven más eficientes en las copias, queremos acceder a esas funciones automáticamente.

Tengo una implementación básica en funcionamiento en MacOSX y FreeBSD, pero necesito configurar algunos sistemas más para probarlo.

Creo que este trabajo es ortogonal para hacer que el archivo se mueva de forma asincrónica. Uno no debe interponerse en el camino del otro. Para los proyectos de voluntariado, la pérdida de alcance es enemiga de la productividad.

Los cambios están aquí: https://github.com/transmission/transmission/compare/master...RobCrowston : kernelcopy-wip

En resumen, creo una nueva abstracción llamada tr_sys_path_copy (). (Fui con una copia en lugar de un movimiento porque cuando hacemos de esto una operación asincrónica, puede ser necesario mantener el archivo original durante un período de tiempo indeterminado después de que se completa la copia para cerrar los identificadores de archivo en otros subprocesos).

Hasta ahora, he compilado y ejecutado la nueva prueba (transmisión-prueba-copia) en MacOS 10.15.1, Windows Server 2016, Linux 5.0 (Ubuntu 19.05), Linux 5.3 (Arch 2019-12-03), FreeBSD 12.1 (usa respaldo del espacio de usuario) y FreeBSD 13. En cada caso verifiqué con un depurador que estamos haciendo las llamadas al sistema apropiadas. Desafortunadamente, no pude obtener el código para construir en OpenBSD 6.5, NetBSD 8.1 o Solaris 10 debido a algunos problemas de libevent no relacionados, pero no estoy seguro de que estas sean plataformas compatibles con libtransmission. En cualquier caso, este cambio no debería afectar a esas plataformas.

Todavía por hacer:

  • Pruebe en un kernel de Windows más antiguo. Necesita configurar un entorno de desarrollo de máquina virtual para eso.
  • Pruebe la copia de volumen cruzado (ya que eso es lo que nos importa). Sin embargo, no estoy seguro de cómo hacer eso como una prueba automatizada.
  • Pruebe el archivo tr_sys_path_copy () para un archivo razonablemente grande (> 100 GB). Probablemente no se pueda realizar como una prueba automatizada.
  • Pruebe in situ en lugar de simplemente probar tr_sys_path_copy () de forma aislada.
  • Reemplace uno de mis servidores bit torrent con este código por un tiempo, vea cómo se comporta en el mundo real.

Comentarios bienvenidos.

+1 para hacer que los movimientos de datos sean asincrónicos. Mover grandes torrents entre sistemas de archivos bloquea toda la aplicación .

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

JustMyGithub picture JustMyGithub  ·  5Comentarios

hanklank picture hanklank  ·  3Comentarios

crozone picture crozone  ·  6Comentarios

mattia-b89 picture mattia-b89  ·  7Comentarios

boingo-00 picture boingo-00  ·  3Comentarios