让我们想象一下这种情况。我的 btrfs 磁盘上有 20GB 文件,但只剩下 10GB 空间。我创建快照,然后修改文件。如何将该文件恢复为存储在快照中的原始文件?
我认为这是不可能的。是的,我可以挂载快照,然后将文件从快照复制回主文件系统。但它无法容纳,因为它比剩余空间大。那么我可以删除更改的文件以释放空间吗?不,因为删除文件不会增加可用空间,它是btrfs。为了释放空间,我必须删除快照,但这样我就会丢失原始文件。所以我认为唯一的办法是:
- 挂载快照
- cp 文件到外部文件系统(外部存储)
- 删除更改的文件
- 删除快照
- 将原始文件从外部存储复制回来
关于不同的解决方案有什么想法吗?
答案1
这是可能的,而且很容易。只需cp
使用以下内容就足够了--reflink=always
:
cp --reflink=always /path/to/desired/file /target/directory/
--reflink=always
至关重要。此外,您可能想使用-a
.
当有疑问时,合理的做法是复制到另一个名称,即不要贸然覆盖修改后的文件。这样,您将能够从 获得成功cp
,检查结果并确保它是正确目录中的正确文件,然后覆盖修改后的文件(在mv
目标目录中)。
有了足够新的 Linux 内核(5.18或以上)如果只有所需的文件和目标目录位于同一 Btrfs 文件系统中(这显然是您的情况),该命令应该可以工作。
如果您的内核不够新,那么您可能会收到Invalid cross-device link
错误消息。如果您尝试cp --reflink=always
跨挂载点,您将收到此错误。仍然可以将所需的文件重新链接到所需的目录,您只需在单个安装点下执行此操作即可。因此,如果您得到了,Invalid cross-device link
请像这样继续:
将整个 Btrfs 文件系统 (
subvol=/
) 挂载到/some/mountpoint
.关键是我们希望所需的文件和目标目录出现在
/some/mountpoint
.根据文件系统中子卷的布局(树),您可以通过安装某些子卷(不一定是整个文件系统)来完成此操作。通过安装整个文件系统,您肯定会达到预期的结果。也许您正在运行的操作系统中已经存在满足此要求的安装点,您可以使用它。对比一下这个答案:btrfs:浏览子卷。
用于
cp --reflink=always
将所需文件复制到目标目录,就像上面一样。重要的是保持在 下/some/mountpoint
,即使具有目标目录的子卷(也)安装在其他地方。不要交叉安装点。将整个文件系统挂载在一个挂载点上正是为了让您能够cp
在单个挂载点下进行操作。umount /some/mountpoint
(除非您使用现有的安装座)。