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

时间:2015-09-29 18:52:57

标签: linux linux-kernel filesystems ext4

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

  • FILE_SIZE <= min(page_size, physical_block_size);
  • 文件大小永远不会更改(即永远不会执行truncate()或附加write());
  • 文件仅通过使用以下方式完全覆盖其内容进行修改:

    pwrite(fd, buf, FILE_SIZE, 0);
    

ext4是否保证:

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

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

  3. 第二个是真的吗?

    • data=ordered
    • 使用data=journal
    • 或者为单个文件启用了日记功能?

      (使用ioctl(fd, EXT4_IOC_SETFLAGS, EXT4_JOURNAL_DATA_FL)

    • 何时physical_block_size < FILE_SIZE <= page_size

    我发现related question与2011年的discussion相关联。但是:

    • 我没有找到问题2的明确答案。
    • 我想知道,如果上述情况属实,是否记录某处?

2 个答案:

答案 0 :(得分:4)

从我的实验来看,这不是原子的。

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

作家流程:

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

读者流程

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

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

因此它明确表明写入不是原子的。在我的情况下,16byte写入总是原子的。

答案是:除了管道之外,POSIX不会要求写入/读取的原子性。我看到的16字节原子性是内核特定的,将来可能会改变。

实际帖子中的答案详情: write(2)/read(2) atomicity between processes in linux

答案 1 :(得分:2)

我对文件系统的理论很熟悉,而不是Ext4的实现。以此作为有根据的猜测。

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

  • Link you provided引用&#34;目前并发读/写只是单个页面的原子,但不在系统调用上。 &#34;
  • 磁盘扇区(512字节)写入是原子according to Stephen Tweedie。在私人电子邮件conversation中,他承认这种保证与硬件一样好。
  • Ext文件系统就地覆盖数据,写入时不复制。没有分配。
  • some effort来实现内联数据,非常小的文件数据可以适合inode本身。如果您只需要存储少量字节,则可能会产生影响。

不确定是否有一个页面,但在完整日记模式下,在提交之前将少于一页的内容发送到日志中是没有意义的。