“文件数据”和“文件大小”是一起还是单独提交到磁盘

时间:2013-01-21 16:51:19

标签: c file-io synchronization filesize robustness

考虑这个例子:

FILE* stream = fopen("my_file", "w");
fputs("hello", stream);

如果在执行fputs()期间断电,会发生什么?

之后,我能不能找到非零大小的“my_file”,但第一个字节不是'h'? 如果是,是否保证为零,或者它是否包含任意值?

当然,假设没有其他人在触摸我们的档案。

编辑:假设目标磁盘驱动器/设备的类型能够保持足够长的时间来写入它在内部缓冲的所有数据。

POSIX有什么可说的吗? Linux吗?是Windows吗?

编辑:我不打算专注于如何实现STDIO流API的细节。假设POSIX,这就是我的意思:

int fd = open("my_file", O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
write(fd, "hello", 5);

编辑:POSIX将大小视为文件的元数据,因此问题可能会被重新描述为:由于代码,文件数据和该文件的元数据是否可以在不同的阶段提交到磁盘以上?

编辑:在http://www.sqlite.org/atomiccommit.html中找到了这个:

  

7.5具有安全附加语义的文件系统

     

SQLite版本3.5.0中引入的另一个优化可以使用   底层磁盘的“安全附加”行为。回想起那个   SQLite假定将数据附加到文件(特别是   回滚日志)文件的大小增加   首先,内容写在第二位。所以如果断电了   文件大小增加后但内容之前   写入后,文件中包含无效的“垃圾”数据。该   但是,VFS的xDeviceCharacteristics方法可能表示   文件系统实现“安全附加”语义。这个   表示在文件大小之前写入内容   增加,以便垃圾不可能被引入   通过断电或系统崩溃进入回滚期刊。

这似乎提供了至少部分答案。

2 个答案:

答案 0 :(得分:1)

关于linux,您写入缓冲区的内容不能保证写入磁盘immediatley。

kerneldata复制到buffer中,稍后在后台,内核会收集所有dirty buffers,对其进行最佳排序并将其写入disk。这称为writeback。这允许写入调用快速发生,几乎立即返回。它还允许内核defer writes更多idle periods并批量许多writes together

答案 1 :(得分:0)

这在很大程度上取决于正在使用的文件系统(ext3ext4xfs,....)以及给定的挂载时间选项,因此没有一个简单的一刀切的答案。也许如果你向我们展示你的/etc/fstab并告诉我们你想知道哪个文件系统,可以给出更好的答案......