Primero, fsync()
(y sync()
) son funciones estándar de POSIX, mientras que syncfs()
es solo para Linux.
Así que la disponibilidad es una gran diferencia.
Del estándar POSIX para fsync()
:
El fsync()
función solicitará que todos los datos para el descriptor de archivo abierto nombrado por fildes
se transferirá al dispositivo de almacenamiento asociado con el archivo descrito por fildes
. La naturaleza de la transferencia está definida por la implementación. El fsync()
La función no regresará hasta que el sistema haya completado esa acción o hasta que se detecte un error.
Tenga en cuenta que es solo una solicitud.
Del estándar POSIX para sync()
:
El sync()
hará que toda la información en la memoria que actualice los sistemas de archivos sea programada para escribir a todos los sistemas de archivos.
La escritura, aunque programada, no está necesariamente completa al regresar de sync()
.
Una vez más, eso no es algo que suceda garantizado.
La página del manual de Linux para syncfs()
(y sync()
) estados
sync()
hace que todas las modificaciones pendientes en los metadatos del sistema de archivos y los datos de archivos almacenados en caché se escriban en los sistemas de archivos subyacentes.
syncfs()
es como sync()
, pero sincroniza solo el sistema de archivos que contiene el archivo al que hace referencia el descriptor de archivo abierto fd
.
Tenga en cuenta que cuando la función devuelve no está especificada.
El Linux página man para fsync()
estados:
fsync()
transfiere ("descarga") todos los datos internos modificados de (es decir, páginas de caché de búfer modificadas para) el archivo al que hace referencia el descriptor de archivo fd
al dispositivo de disco (u otro dispositivo de almacenamiento permanente) para que toda la información modificada pueda recuperarse incluso si el sistema falla o se reinicia. Esto incluye escribir o vaciar la memoria caché del disco, si está presente. La llamada se bloquea hasta que el dispositivo informa que la transferencia se ha completado.
Además de vaciar los datos del archivo, fsync()
también vacía la información de metadatos asociada con el archivo (ver inode(7)).
Llamando al fsync()
no garantiza necesariamente que la entrada en el directorio que contiene el archivo también haya llegado al disco. Por eso un fsync()
explícito También se necesita un descriptor de archivo para el directorio.
Tenga en cuenta que las garantías que proporciona Linux para fsync()
son mucho más fuertes que los provistos para sync()
o syncfs()
y por POSIX para ambos fsync()
y sync()
.
En resumen:
- POSIX
fsync()
:"escriba los datos de este archivo en el disco" - POSIX
sync()
:"escribir todos los datos en el disco cuando llegue a él" - Linux
sync()
:"escribir todos los datos en el disco (¿cuándo lo haces?)" - Linux
syncfs()
:"escribir todos los datos para el sistema de archivos asociado con este archivo en el disco (¿cuando llegue a él?)" - Linux
fsync()
:"escriba todos los datos y metadatos de este archivo en el disco y no regrese hasta que lo haga"
Tenga en cuenta que la página de manual de Linux no especifica cuando sync()
y syncfs()
volver.
Creo que la respuesta actual no está completa. Para Linux:
Según la especificación estándar (por ejemplo, POSIX.1-2001), sync()
programa las escrituras, pero puede regresar antes de que se complete la escritura real. Sin embargo, Linux espera que se complete la E/S y, por lo tanto, sync()
o syncfs()
proporcionar las mismas garantías que fsync
llamado en cada archivo en el sistema o sistema de archivos respectivamente.
y
Antes de la versión 1.3.20, Linux no esperaba a que se completara la E/S antes de regresar.
Esto se menciona en el sync(2)
página en las secciones "notas" y "errores".