我在一个文件中有一个 luks 加密的 ext4,我用它来存储敏感数据(让我们将此 FS 称为“内部”)。文件本身又位于另一个 ext4 上,该 ext4 驻留在物理 SSD 上。让我们称其为“外部”FS。内部 FS 使用指向外部 FS 上文件的环回设备进行安装。
当我调用sync(1)时,是否能保证内部FS的所有挂起写入都被持久化?
如果同步以不幸的顺序发生,则(根据我的理解)可能会发生以下情况:
- 数据写入内部 FS。
sync
调用。- 外部 FS 缓存的写入被写入磁盘。
- 内部 FS 缓存的写入将写入外部 FS 上的文件。
- 从内部 FS 到外部 FS 的写入仍然在缓存中。
- 发生崩溃。
- 尽管这样,对内部 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 也很可能使用此方法。
这似乎是您不喜欢的,因此在您的情况下应该发出的不仅仅是同步调用。