具有写时复制硬链接的文件系统

具有写时复制硬链接的文件系统

研究案例:

通过 OpenVPN 实现所有家庭成员的自动备份系统。

许多文件(尤其是照片)是家庭成员之间共享的。

因此,我使用脚本用硬链接替换相同的文件。

然后出现一个问题:如果用户更改了其文件,则所有用户的文件都会更改。删除文件不是问题,重命名也不是问题。只有文件内容会更改。

因此,我希望当用户更改其文件(硬链接)时,硬链接被消除,并且创建应用更改的原始文件的副本。

任何文件系统、任何黑客手段或功能都可能实现这一点吗?

答案1

您正在寻找引用链接该功能于 2009 年推出。它仅适用于某些文件系统 - 目前为 Btrfs,西弗斯以及即将推出的 Bcachefs。(ZFS 仍然正在努力

在可能的情况下使用--reflink创建 CoW 副本(这已经是 coreutils 9.0 的默认设置),或者--reflink=always如果您想确保它永远不会退回到执行完整复制:

cp --reflink OLDFILE NEWFILE

新文件将具有不同的 inode,但最初将与原始文件共享所有数据范围(可以使用filefrag -v FILE或进行比较xfs_io -rc "fiemap -v" FILE)。


另一种选择是文件系统重复数据删除,它由 Btrfs 和 ZFS 等支持,并允许合并现有文件下的相同块。在 ZFS 中这是同步发生的(“在线”或文件写入后立即发生),而在 Btrfs 中它是作为批处理作业完成的(即“离线”,使用诸如 Bees 或“duperemove”之类的工具)。不幸的是,ZFS 中的在线重复数据删除对资源使用有重大影响。但是,如果您使用 Btrfs,则可以duperemove -rd偶尔针对文件夹运行一次。

最后,无论你使用 reflinks 还是 dedupe,你还需要使用可以执行重复数据删除的备份工具(这是不是足以使用硬链接感知备份工具,因为 reflink 看起来不像硬链接)。例如,Restic 和 Borg 使用的存档格式是内容寻址的(很像 Git),因此相同的块将自动在每个存储库中仅存储一次,即使它们出现在单独的文件中。


Linux 上的 OCFS2 集群文件系统至少在名称上也有“reflinks”,但不支持标准 reflink 创建 API,因此必须使用 OCFS2 特定的工具来创建它们。

在 Windows 上,ReFS 支持名为“块克隆”的 reflink(尽管它似乎没有内置 CLI 工具);NTFS 则不支持。最后在 macOS 上,cp -c只要您使用 APFS,就会创建 reflink(CoW 副本)。

答案2

另一种可能性是设置粘滞位设置的共享目录

在 Linux 系统上,/tmp 目录具有权限 drwxrwxrwt(或用数字表示为 1777),这确保任何人都可以向其中写入任何内容,但是一旦执行了这些操作,这些文件就属于他们,其他用户无法修改或删除,因此您保留了文件所有权的概念。

因此,您可以创建一个具有相同权限的目录作为一种组目录。

这并不完全按照您上面描述的方式工作,但它确实确保用户可以将他们喜欢的任何文件放入他们自己创建的新目录或根目录中,并且其他用户无法删除或修改属于其他用户的任何文件。目录上的粘性位是实现第二部分的原因 - 通常,如果您授予目录可全局写入权限,那么人们可以删除其他人的文件。使用粘性位,人们无法删除或修改不属于他们的文件。

对于您希望任何人都能阅读的任何公共文件,您只需将其放入其中并将其保留为您所有。

注意:与您的问题不同,其他人无法修改或删除这些文件,但他们只需要被告知,他们可以在他们喜欢的任何地方设置自己的副本并进行修改。

这样做的缺点是,如果某样东西不属于他们,他们就无法透明地删除或修改它。

但这种解决方案的好处是,他们放入的所有内容都会与其他人共享,所有人都可以打开并阅读它。

答案3

通过一些规划,你可以实现你想要的覆盖文件系统

您需要将所有实例共有的所有文件放入通常只读的下部目录中。

然后,用户使用 overlayfs 在其上方挂载一个单独的上层目录,用于您想要的每个可进行不同修改的副本。上层目录一开始可以为空,这意味着每个人只查看下层目录中未修改的内容。

当任何已安装的覆盖层中的现有文件被修改时,它会导致文件被复制到上层目录并仅为该实例覆盖它。这是完全透明的。删除和新建文件也是如此 - 这只会影响当前正在使用的上层目录。进行更改的用户将在其实例中看到它,但不会影响下层目录或其他人的实例。

随着时间的推移,如果不同的人将不同的东西添加到他们自己的实例中,它们最终会变得越来越不同,但是如果您想合并事物,您可以定期检查并确定所有用户应该相同的任何内容,然后将其移动到通常只读的下部目录中。

仅有的我可以预见到此设置(两种解决方案都一样)的问题是,如果用户想要与其他用户共享文件,他们添加的任何内容都不会被共享,并且只有他们自己可见。如果您想要这样,还有另一种可能性。

相关内容