在 ext4 上覆盖一个小文件是原子的吗?

Is overwriting a small file atomic on ext4?

假设我们有一个 FILE_SIZE 字节的文件,并且:


ext4 是否保证:

  1. 这样的写入相对于并发读取是原子的?
  2. 这样的写入对于系统崩溃是事务性的吗?

    (即,崩溃后文件的内容完全来自之前的一些写入,我们永远不会看到部分写入或空文件)

第二个是否为真:


我发现 related question which links discussion 是 2011 年的。但是:

我熟悉文件系统的一般理论,但不熟悉 Ext4 的实现。以此作为有根据的猜测。

是的,我相信一个扇区的读写是原子的,因为

  • Link you provided 引用 "Currently concurrent reads/writes are atomic only wrt individual pages, however are not on the system call. "
  • 磁盘扇区(512 字节)写入对他来说是原子的according to Stephen Tweedie. In private email conversation,他承认这种保证仅与硬件一样好。
  • Ext 文件系统就地覆盖数据,写入时不复制。没有分配。
  • some effort实现内联数据,非常小的文件数据可以放入inode本身。如果您只需要存储几个字节,那可能会产生影响。

不确定一页,但在完整日志记录模式下,在提交之前向日志发送少于一页是没有意义的。

根据我的实验,它不是原子的。

基本上我的实验是有两个过程,一个作家和一个reader。编写器循环写入文件,reader 从文件中读取

编写器进程:

char buf[][18] = {
    "xxxxxxxxxxxxxxxx",
    "yyyyyyyyyyyyyyyy"
};
i = 0;
while (1) {
   pwrite(fd, buf[i], 18, 0);
   i = (i + 1) % 2;
}

Reader 进程

while(1) {
    pread(fd, readbuf, 18, 0);
    //check if readbuf is either buf[0] or buf[1]
}

经过 运行 两个过程一段时间后,我可以看到 readbufxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyxx

因此它明确表明写入不是原子的。在我的例子中,16 字节写入总是原子的。

答案是:POSIX 不要求 writes/reads 的原子性,管道除外。我看到的 16 字节原子性是内核特定的,may/can 将来会改变。

实际回答详情post: