我在linux下有一些c应用程序。我正在重命名一些文件,rename(...)
如何确保将重命名持久写入底层磁盘?
使用文件,我可以执行以下操作:
FILE * f = fopen("foo","w");
...
fflush(f);
fsync(fileno(f));
fclose(f);
我如何fsync
(或类似)rename()
在 c 中的 a 之后的目录?
我在linux下有一些c应用程序。我正在重命名一些文件,rename(...)
如何确保将重命名持久写入底层磁盘?
使用文件,我可以执行以下操作:
FILE * f = fopen("foo","w");
...
fflush(f);
fsync(fileno(f));
fclose(f);
我如何fsync
(或类似)rename()
在 c 中的 a 之后的目录?
这就是你可以做你想做的事:
#include <fcntl.h>
int fd = open('/path/to/dir', O_RDONLY);
fsync(fd);
当然,不要忘记fd
在不再需要时关闭文件描述符。
与一些误解相反,原子性rename()
并不能保证文件会被持久化到磁盘。原子性保证仅确保文件系统缓冲区中的元数据处于一致状态,但不能确保它已持久化到磁盘。
rename()
是原子的(在linux上),所以我认为你不需要担心
原子性通常在涉及文件名处理的操作中得到保证;例如,对于重命名,“规范要求函数的操作是原子的”——也就是说,当将文件从旧名称重命名为新名称时,在任何情况下都不应同时看到这两个文件。
rename() 操作过程中的断电不应使文件系统处于“奇怪”状态,因为文件名的元数据已损坏,因此无法访问。(即,要么操作丢失,要么操作已提交。)
所以,我认为你应该只担心错误值。
如果您真的想要安全,fsync()
还可以刷新元数据(在 linux 上),这样您就fsync
可以确保磁盘上存在您想要的目录和文件。
根据手册,在函数返回时,rename
已有效完成(返回 0)或发生错误(返回 -1),并errno
设置为检查问题所在。
如果您希望系统仅在此文件上应用潜在的挂起修改,rename
您可以执行以下操作:
int fd = open(new_name, O_RDONLY);
syncfs(fd);