是否可以保证嵌套文件系统在使用sync(1) 的包含文件系统之前同步?

Jon*_*fer 6 linux filesystems cache mount

我在一个文件中有一个 luks 加密的 ext4,我用它来存储敏感数据(让我们将此 FS 称为“内部”)。文件本身又位于另一个 ext4 上,该 ext4 驻留在物理 SSD 上。让我们称其为“外部”FS。内部 FS 使用指向外部 FS 上文件的环回设备进行安装。

\n\n

当我调用sync(1)时,是否能保证内部FS的所有挂起写入都被持久化?

\n\n

如果同步以不幸的顺序发生,则(根据我的理解)可能会发生以下情况:

\n\n
    \n
  1. 数据写入内部 FS。
  2. \n
  3. sync调用。
  4. \n
  5. 外部 FS 缓存的写入被写入磁盘。
  6. \n
  7. 内部 FS 缓存的写入将写入外部 FS 上的文件。
  8. \n
  9. 从内部 FS 到外部 FS 的写入仍然在缓存中。
  10. \n
  11. 发生崩溃。
  12. \n
  13. 尽管发生在某个事件之前,但对内部 FS 的写入仍会丢失sync.
  14. \n
\n\n

同步是否能保证这种情况不会发生,或者我是否必须调用同步与嵌套文件系统层的次数一样多才能确定?

\n\n

我要求的是 Linux,但如果 POSIX 有这方面的消息,我\xe2\x80\x99d 也会对此感兴趣。

\n\n

sync(1)或上的 Debian 联机帮助页sync(2)没有关于此情况的信息。

\n

phe*_*mer 3

是的,这是有保证的。
您没有明确说明如何执行嵌套文件系统,但我假设您正在使用块环回设备。

在这种情况下,可以在内核源代码中看到关键位:

static int lo_req_flush(struct loop_device *lo, struct request *rq)
{
    struct file *file = lo->lo_backing_file;
    int ret = vfs_fsync(file, 0);
    if (unlikely(ret && ret != -EINVAL))
        ret = -EIO;

    return ret;
}
Run Code Online (Sandbox Code Playgroud)

请注意对 的调用vfs_fsync(file, 0)。这意味着环回驱动程序正在支持环回块设备的文件上显式调用同步。

  • “这是对 fsync() 的调用”。是的。正如我在答案中所解释的,这是对支持文件上的 fsync 的调用。函数“lo_req_flush”由“sync()”调用。如果你要批评,请明白你批评的是什么。 (2认同)