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

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

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

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

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

  1. 数据写入内部 FS。
  2. sync调用。
  3. 外部 FS 缓存的写入被写入磁盘。
  4. 内部 FS 缓存的写入将写入外部 FS 上的文件。
  5. 从内部 FS 到外部 FS 的写入仍然在缓存中。
  6. 发生崩溃。
  7. 尽管这样,对内部 FS 的写入仍会丢失发生在之前A sync

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

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

sync(1)不幸的是, Debian 手册页上sync(2)没有关于此案例的信息。

答案1

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

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

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;
}

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

答案2

该命令没有授权,但最可能的方式是内核在sync(2)被调用时遍历挂载表。 Solaris 使用此方法,Linux 也很可能使用此方法。

这似乎是您不喜欢的,因此在您的情况下应该发出的不仅仅是同步调用。

相关内容