¿Por qué no hay llamadas de sistema de inserción de archivos?

11

Según tengo entendido, para manipular archivos solo hay sys_write syscall en Linux, que sobrescribe el contenido del archivo (o lo extiende, si al final).

¿Por qué no hay syscalls para insertar o eliminar contenido en archivos en Linux?

Como todos los sistemas de archivos actuales no requieren que el archivo se almacene en un bloque de memoria continuo, debería ser posible una implementación eficiente. (Los archivos se fragmentarían).

Con las características del sistema de archivos como "copiar al escribir" o "compresión transparente de archivos", la forma actual de insertar contenido parece ser muy ineficiente.

dercolamann
fuente
44
Como con todas las operaciones de archivo sofisticadas, dicha operación es mucho menos útil en la práctica de lo que parece. El uso principal para tal cosa son aplicaciones muy especializadas, como bases de datos, emuladores y demás. La forma en que normalmente "edita" un archivo es creando un archivo nuevo y haciendo que el usuario realice una operación de "guardar" y cambie el nombre del archivo nuevo al antiguo.
mosvy
3
@mosvy, pero ¿se utiliza el concepto "crear nuevo archivo, luego renombrar" porque es bueno en sí mismo o exactamente porque el sistema no proporciona una mejor manera? Especialmente en archivos de texto, las operaciones como "modificar esta línea (cambiando la longitud)" o "insertar estas líneas aquí" son bastante comunes, por lo que se podría suponer que las operaciones del sistema de archivos para esas funciones exactas se usarían si estuvieran allí. Por supuesto, no tener que hace que la implementación fs mucho más simple ...
ilkkachu
1
@meuh OpenVMS todavía lo hace, a través de RMS (Record Management Services).
RonJohn
1
UNIX comenzó un movimiento lejos de proporcionar sistemas de gestión de registros dentro del sistema de archivos.
user207421
1
@ilkkachu es bueno en sí mismo, absolutamente sin duda ;-) Aún más, si los inodos fueran inmutables, eso hará que la implementación del uso compartido de bloques, el control de versiones y casi todo sea mucho más eficiente (y mucho más simple de razonar). Piense por analogía cómo todos los lenguajes de script han cambiado a cadenas inmutables, pero lo resumiré aquí; es difícil hablar de los sistemas de archivos y no sonar como un charlatán ;-)
mosvy

Respuestas:

22

En sistemas Linux recientes eso es realmente posible, pero con bloque (4096 la mayor parte del tiempo), no granularidad de bytes , y solo en algunos sistemas de archivos (ext4 y xfs).

Citando de la página de fallocate(2)manual:

int fallocate(int fd, int mode, off_t offset, off_t len);

[...]

Colapsar espacio de archivo

Al especificar el FALLOC_FL_COLLAPSE_RANGEindicador (disponible desde Linux 3.15) se modeelimina un rango de bytes de un archivo, sin dejar un agujero. El rango de bytes que se contraerá comienza en offsety continúa para len bytes. Al finalizar la operación, el contenido del archivo que comienza en la ubicación offset+lense agregará en la ubicación offsety el archivo será de lenbytes más pequeños.

[...]

Aumentando el espacio de archivo

Especificar el FALLOC_FL_INSERT_RANGEindicador (disponible desde Linux 4.1) modeaumenta el espacio de archivo insertando un agujero dentro del tamaño del archivo sin sobrescribir ningún dato existente. El agujero comenzará en offsety continuará por lenbytes. Al insertar el agujero dentro del archivo, el contenido del archivo que comienza en offsetse desplazará hacia arriba (es decir, a un mayor desplazamiento del archivo) por lenbytes. Insertar un agujero dentro de un archivo aumenta el tamaño del archivo en lenbytes.

Mosvy
fuente
1
"pero con bloque (4096), no granularidad de bytes" : los bloques 4KiB son muy comunes en ext4, pero eso no está garantizado. Ext4 admite tamaños de bloque de 1 KB, 2 KB y 4 KB ; y recuerdo de los días ext2 que en los procesadores Alpha, 8KiB también era compatible. No puedo asumir que los bloques son 4KiB, me temo.
marcelm
1
4k (que es el valor predeterminado) es un múltiplo de 1k y 2k, por lo que no hay problema al asumir 4k con ext4. Si bien xfs también tendrá un valor predeterminado de 4k, se supone que admite una bs mayor que 4k, hasta 64k, pero solo pude crear una fs de este tipo; el montaje falla sin ENOSYS. Y de todos modos, no puedes asumir nada: esta función no es compatible con todos los fs, por lo que es mejor decir block = 4096, para que el lector tenga un cierto sentido de proporción, en lugar de dejar que flote y dejar que las personas puedan ser cualquier cosa, o peor, que es de 512 bytes o que de alguna manera está relacionado con el tamaño de página vm.
mosvy
Después de editar (donde dices que usualmente es 4KiB), ¡estoy totalmente de acuerdo! Mi problema era que anteriormente se leía fácilmente como "los bloques son siempre 4KiB" , lo que puede hacer que la gente haga esa suposición y escriba código defectuoso.
marcelm
9

Como todos los sistemas de archivos actuales no requieren que el archivo se almacene en un bloque de memoria continuo,

Es posible que los sistemas de archivos no requieran que los archivos se almacenen en un área continua (y eso sería muy inflexible), pero generalmente los archivos se almacenan en bloques de tamaño fijo (o secuencias de bloques contiguos). Hacerlo de esa manera simplifica la implementación, y los bloques suelen ser múltiplos del tamaño del bloque del dispositivo subyacente.

Por lo tanto, la implementación de insertos de bloques con una longitud arbitraria haría que el formato y la implementación del sistema de archivos sean bastante más complejos o que requiera mover cantidades potencialmente grandes de datos. Ninguno de los dos es realmente bueno, y se pueden construir estructuras de datos complejas en el espacio de usuario sobre la API del sistema de archivos.

ilkkachu
fuente