Tengo una utilidad que escribí hace años en C ++ que toma todos los archivos en todos los subdirectorios de un directorio determinado y los mueve a nuevos subdirectorios numerados según el recuento de los archivos. Ha funcionado sin error durante varios años.
Ayer falló por primera vez. Siempre falla en un archivo de video de 2.7Gig, quizás el más grande que haya encontrado esta utilidad. El archivo en sí no está dañado. Se reproducirá en un reproductor de video. Puedo moverlo con aplicaciones de línea de comandos o administrador de archivos sin ningún problema.
Uso ntfw() para recorrer el subárbol del directorio. En este archivo, ntfw() devuelve un código de error de -1 al encontrar el archivo, antes de llamar a mi función de devolución de llamada. Dado que (pensé) el código solo se ocupa de los nombres de archivo y no abre ni lee el archivo, no entiendo por qué el tamaño del archivo debería ser un problema.
El número de descriptores de archivos abiertos no es el problema. Ni el número de archivos. Estaba en un subárbol de más de 5000 archivos, pero al moverlo a uno de solo 50 todavía falla, mientras que el subárbol original se procesa sin errores. Los permisos de archivo no son el problema. Este archivo tiene lo mismo que todos los demás. Esto incluye los permisos de ACL.
La pregunta es: ¿el tamaño del archivo es el problema? ¿Por qué?
El sistema de archivos es ext4.
ldd --version /usr/lib/i386-linux-gnu/libc.so ldd (Ubuntu GLIBC 2.27-3ubuntu1.4) 2.27 Linux version 4.15.0-161-generic (buildd@lgw01-amd64-050) (gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)) #169-Ubuntu SMP Fri Oct 15 13:39:59 UTC 2021Como está utilizando una aplicación de 32 bits, para que funcione correctamente con archivos de más de 2 GB, debe compilar con -D_FILE_OFFSET_BITS=64 para utilizar tipos y llamadas al sistema de manejo de archivos de 64 bits.
En particular, nftw() llama a stat() que falla con EOVERFLOW si el tamaño del archivo supera los 2 GB: https://man7.org/linux/man-pages/man2/stat.2.html
Además, para usar mmap () (que parece que no está usando, pero en caso de que lo mencionara un comentario), no puede asignar todos los 4 GB, parte del espacio de direcciones está reservado para el núcleo ( típicamente 1 GB en Linux). Luego, las pilas, las bibliotecas compartidas, etc. utilizan algo de espacio. Tal vez pueda mapear 2 GB a la vez, si tiene suerte.