Recuerdo vagamente haber leído en algún lugar que solía haber, en algunos Unices, una forma de abrir un archivo existente para escribir, con una bandera que le pedía al kernel que usara la versión anterior (para que otros procesos accedan a ella para leer), hasta que aparezca "nuevo "la versión estaba completamente escrita (fd cerrado), desde ese momento el archivo apareció como la nueva versión.
En otras palabras, otros procesos vieron la versión anterior, o la nueva, nunca una incompleta.
¿Alguien conocedor puede señalarme una referencia?
kernel
open-files
eudoxos
fuente
fuente
Respuestas:
Lo que estás describiendo suena exactamente como un cambio de nombre básico para sobrescribir un archivo.
Cuando cambia el nombre / mueve un archivo encima de otro, el archivo antiguo se desvincula. Lo que significa que el archivo todavía existe, pero ya no está en el árbol del sistema de archivos. Por lo tanto, las aplicaciones antiguas continuarán pudiendo acceder al archivo siempre que lo mantengan abierto. Una vez que todas las aplicaciones han cerrado el archivo anterior, entonces no está asignado en el disco.
La
rename
llamada al sistema es una operación atómica. Para hacer esto, debe crear un nuevo archivo con un nombre diferente y luego llamarrename
para cambiar el nombre del archivo temporal como el que desea reemplazar. Como la operación es atómica, no hay absolutamente ningún período en el que falte el archivo. Al instante pasa del archivo antiguo al archivo nuevo.Sin embargo, tenga en cuenta que el archivo temporal y el archivo que se va a reemplazar deben residir en el mismo punto de montaje.
fuente
rename
intercambio. Incluso si existiera una 'característica del sistema operativo' de la que está hablando, el programa también tendría que escribirse para aprovechar eso también. ¿Cual es la diferencia?open
llamada al sistema o si tiene que hacer lo que describe a mano.Como Patrick escribe , la forma habitual de hacer esto es escribir la nueva versión en un archivo separado y, cuando termine, cambie el nombre de la nueva versión al antiguo nombre de archivo, sobrescribiéndola atómicamente. Esta segunda operación se llama sobrescribir por cambio de nombre .
Ahora, algunas referencias:
ISO C requiere
rename
ser atómico. De las especificaciones de Open Group Base :Las versiones anteriores de Mac OS X no tenían cambios de nombre atómicos; Según los informes, esto se soluciona en Lion.
Btrfs aparentemente viola intencionalmente el estándar al no garantizar los cambios de nombre atómicos , por razones de rendimiento. Sin embargo, la sobrescritura por cambio de nombre sigue siendo atómica , que es todo lo que necesita para este propósito.
fuente
man 3p rename
me dice querename
es atómico, y supongo que está destinado a todos los sistemas de archivos Linux. Y cuando leí el primer artículo que vinculaste, sigo pensando que las operaciones de cambio de nombre de Btrfs son atómicas.Esto me recuerda a Allocate On Flush . Cuando un sistema de archivos usa esta función, en lugar de escribir datos directamente en el disco, resta el tamaño de los datos que se escribirán en el contador de espacio libre del disco y retiene los datos en la memoria hasta que se realiza una llamada al sistema de sincronización o el núcleo decide para limpiar los tampones sucios.
En este caso, si un archivo está modificando el archivo y otro proceso lo abre, este último proceso "verá" la versión del archivo sin modificar ( o "antigua" si lo prefiere ).
Por supuesto, lo anterior es teórico y depende de varios factores, y diría que es un poco impredecible, ya que no sabe exactamente cuándo el núcleo va a enjuagar las páginas sucias. Por ejemplo, en Linux ( como también puede leer en la sección 15.3 de Comprensión del kernel de Linux ), las páginas sucias se escriben en el disco bajo las siguientes condiciones:
El caché de la página se llena demasiado y se necesitan más páginas, o la cantidad de páginas sucias se vuelve demasiado grande.
Ha transcurrido demasiado tiempo desde que una página se mantuvo sucia.
Un proceso solicita que se vacíen todos los cambios pendientes de un dispositivo de bloque o de un archivo en particular; lo hace invocando una llamada al sistema sync (), fsync () o fdatasync ().
Se sabe que esta característica se implementa en los sistemas de archivos HFS +, XFS, Reiser4, ZFS, Btrfs y ext4.
fuente