Expand description
把容器里保存的元数据还原到落盘的文件上。
§为什么单独一个模块
crate::pack 负责采集,这里负责还原,两边共用
crate::container::EntryMeta。放在 core 而不是各前端里的理由与
pack 相同:CLI 和 GUI 都要解容器,两份实现迟早分歧——尤其还原策略
本身有大量平台分支,复制一份等于把平台差异也复制一遍。
§为什么「尽力还原」而不是「失败即报错」
文档 05 §4.1 定的策略是按目标平台能力尽力还原,不支持的项明确 报告。这两半都不能少:
- 只要有一项设不上就整个解密失败,等于让用户为了一个时间戳丢掉 全部文件内容——内容是主体,元数据是附属。
- 但静默丢弃更糟:用户以为完整还原了,直到某天发现所有文件的 修改时间都是解密那天。备份场景下这是实质的数据丢失,而且 不可逆——原目录往往已经删了。
所以每一项都试,失败的记进 RestoreReport 交给调用方展示。
§平台差异不猜,按实际能力分支
| 项 | Windows | Unix |
|---|---|---|
| mtime | 支持(100ns 精度) | 支持(1ns) |
| btime(创建时间) | 支持 | Linux 无法设置,报告为不支持 |
| POSIX 权限位 | 无此概念,报告为不支持 | 支持 |
| uid / gid | 无此概念 | 有意不还原,见下 |
uid/gid 在两个平台上都不还原:跨机器的数字 uid 指向的是完全不同的 用户,还原它要么无效要么危险(把文件判给本机的另一个账号)。设置 属主还需要 root,而为了元数据要求提权是本末倒置。仅记录、不还原, 与文档 §4.2 一致。
§目录 mtime:只有新建条目会冲掉它
我起初以为「设置子项的时间会更新父目录的 mtime」,据此把目录拆出来 按深度倒序处理。实测四种操作后发现那是错的:
| 操作 | 父目录 mtime 是否改变 |
|---|---|
| 设置子目录的 mtime | 否 |
| 设置子文件的 mtime | 否 |
| 在目录里新建文件 | 是 |
| 在目录里新建子目录 | 是 |
也就是说只有目录项的增删会动父目录的 mtime,这与 POSIX 对目录 mtime 的定义一致。真正的约束因此不在本模块内部的处理顺序上,而在调用时机: 必须等全部条目落盘之后再来设时间。排序那段复杂度已删除——留着一段 理由已被证伪的代码,比没有它更糟,下一个人会以为这里有个已知陷阱。
Structs§
- Restore
Failure - 单项还原失败的记录。
- Restore
Report - 还原报告。
Enums§
- Unsupported
Kind - 一项元数据未能还原的原因。
Functions§
- restore_
metadata - 把索引里记录的元数据还原到
root下已落盘的条目上。