linux rename ext4 fsync

linux - ¿Es seguro rename() sin fsync()?



ext4 (3)

De la documentación de ext4 :

When mounting an ext4 filesystem, the following option are accepted: (*) == default auto_da_alloc(*) Many broken applications don''t use fsync() when noauto_da_alloc replacing existing files via patterns such as fd = open("foo.new")/write(fd,..)/close(fd)/ rename("foo.new", "foo"), or worse yet, fd = open("foo", O_TRUNC)/write(fd,..)/close(fd). If auto_da_alloc is enabled, ext4 will detect the replace-via-rename and replace-via-truncate patterns and force that any delayed allocation blocks are allocated such that at the next journal commit, in the default data=ordered mode, the data blocks of the new file are forced to disk before the rename() operation is committed. This provides roughly the same level of guarantees as ext3, and avoids the "zero-length" problem that can happen when a system crashes before the delayed allocation blocks are forced to disk.

A juzgar por la redacción de "aplicaciones rotas", los desarrolladores de ext4 definitivamente lo consideran una mala práctica, pero en la práctica es un método tan ampliamente utilizado que fue parcheado en ext4.

Así que si su uso se ajusta al patrón, debería estar seguro.

Si no, le sugiero que siga investigando en lugar de insertar fsync aquí y allá para estar seguro. Puede que no sea una buena idea, ya que fsync puede ser un gran éxito de rendimiento en ext3 ( read ).

Por otro lado, vaciar antes de cambiar el nombre es la forma correcta de realizar el reemplazo en sistemas de archivos que no son de diario. Tal vez por eso ext4 al principio esperaba este comportamiento de los programas, la opción auto_da_alloc se agregó más tarde como una solución. Además, this parche ext3 para el modo de reescritura (no registro en diario) intenta ayudar a los programas descuidados al vaciar de forma asíncrona al cambiar el nombre para reducir la posibilidad de pérdida de datos.

Puedes leer más sobre el problema ext4 here .

¿Es seguro llamar a rename(tmppath, path) sin llamar primero a fsync(tmppath_fd) ?

Quiero que la ruta siempre apunte a un archivo completo. Me preocupo principalmente por Ext4 . ¿Se promete que rename () será seguro en todas las versiones futuras del kernel de Linux?

Un ejemplo de uso en Python:

def store_atomically(path, data): tmppath = path + ".tmp" output = open(tmppath, "wb") output.write(data) output.flush() os.fsync(output.fileno()) # The needed fsync(). output.close() os.rename(tmppath, path)



Si solo te importa ext4 y no ext3, te recomiendo usar fsync en el nuevo archivo antes de cambiar el nombre. El rendimiento de fsync en ext4 parece ser mucho mejor que en ext3 sin los retrasos muy largos. O podría ser el hecho de que la escritura es el modo predeterminado (al menos en mi sistema Linux).

Si solo le importa que el archivo esté completo y no a qué archivo se nombra en el directorio, solo necesita fsync el nuevo archivo. No es necesario fsync el directorio también, ya que apuntará al archivo nuevo con sus datos completos o al archivo antiguo.