第一章:鸿蒙文件系统概览
大家好,我是老李。做嵌入式系统这么多年,文件系统这块我踩过的坑,比走过的路还多。今天咱们聊聊 OpenHarmony 的文件系统架构。说白了,它就是一套管理存储设备的规则,但鸿蒙这套设计,确实有它的独到之处。
1.1 整体架构:三层分工
OpenHarmony 的文件系统,我习惯把它看成三层结构。你想想看,就像公司里的三层管理:顶层定规矩,中层做协调,底层干实事。这三层分别是:
- VFS 层(虚拟文件系统):最上面,面向应用开发者。
- FS 框架层:中间,负责调度和适配。
- 具体文件系统层:最下面,比如 FAT、JFFS2、EROFS。
为什么要这么分?我在项目里遇到过,如果所有逻辑都揉在一起,换一个存储介质就得重写整个驱动。那太痛苦了。鸿蒙这么分层,说白了就是为了「解耦」——上层不用管底层用的是什么闪存芯片。
核心要点:VFS 层提供统一接口,FS 框架层做策略管理,具体文件系统层处理物理存储。这三层各司其职,互不干扰。
1.2 VFS 层:应用眼中的「万能钥匙」
VFS 层,全称 Virtual File System。它的作用很简单:让应用开发者用同一套 API 操作不同文件系统。比如你调用 open()、read()、write(),底层是 FAT 还是 JFFS2,应用根本不用关心。
我记得有一次,团队里新来的同事问:「为什么我格式化了一个分区,代码不用改?」我告诉他,这就是 VFS 的功劳。它把文件操作抽象成了标准接口,底层怎么存,那是驱动的事。
VFS 层主要维护了这些数据结构:
- 超级块(super_block):描述整个文件系统的元信息。
- 索引节点(inode):描述一个文件或目录的元数据。
- 目录项(dentry):描述路径与 inode 的映射关系。
- 文件对象(file):描述一个打开的文件实例。
嗯,这里要注意:VFS 层不负责具体读写,它只做「路由」。你调用 read(),VFS 根据路径找到对应的文件系统,然后转发过去。
1.3 FS 框架层:中间的「调度员」
FS 框架层,是 OpenHarmony 比较有特色的设计。它不像 Linux 那样直接把 VFS 和具体文件系统绑死,而是加了一层「框架」。这层负责什么?
- 挂载管理:决定哪个分区用哪个文件系统。
- 缓存策略:比如 page cache 的刷新时机。
- 权限控制:检查进程是否有读写权限。
- 热插拔支持:SD 卡、U 盘插拔时的处理。
我曾经在一个 IoT 项目里,因为没处理好热插拔,导致系统频繁崩溃。后来发现是 FS 框架层没有正确通知底层文件系统卸载。从那以后,我特别重视这层的「状态机」设计。
FS 框架层还提供了一些钩子函数,方便开发者做定制。比如你想在文件写入前做加密,可以在框架层挂一个回调。这比直接改 VFS 要安全得多。
1.4 具体文件系统层:各显神通
最下面这层,就是真正干活的了。OpenHarmony 支持多种文件系统,每种都有自己的脾气。我挑几个常用的说说:
1.4.1 FAT 文件系统
FAT 是老朋友了,从 DOS 时代就存在。它简单、兼容性好,Windows、Linux、macOS 都能读。但缺点也很明显:
- 单个文件最大 4GB(FAT32 限制)。
- 没有日志功能,突然断电容易丢数据。
- 碎片化严重,用久了性能下降。
我建议:FAT 只用在 SD 卡、U 盘这类需要跨平台交换数据的场景。系统内部分区,尽量别用。
1.4.2 JFFS2 文件系统
JFFS2 是专门为 NOR/NAND Flash 设计的。它有日志功能,不怕突然断电。而且支持磨损均衡,能延长 Flash 寿命。
但 JFFS2 有个毛病:挂载时间特别长。我记得有一次,一个 128MB 的 Flash,挂载花了 30 多秒。为什么?因为它要在启动时扫描整个介质,重建文件系统结构。这在 IoT 设备里是致命的——用户可等不了那么久。
所以,JFFS2 适合小容量、对可靠性要求高的场景,比如存储配置参数。
1.4.3 EROFS 文件系统
EROFS 是华为贡献给 Linux 内核的,后来被 OpenHarmony 采用。它的全称是 Enhanced Read-Only File System。顾名思义,它是只读的。
EROFS 的优势在于:
- 压缩率高:用 lz4 算法,体积能减小 30%-50%。
- 随机读性能好:因为数据布局优化过,适合频繁读取小文件。
- 挂载快:几乎瞬间完成,不像 JFFS2 那样磨叽。
我建议:EROFS 用在系统分区、只读数据分区。比如 /system、/vendor 这些。你想想看,系统镜像一旦烧录就不变了,用只读文件系统既安全又高效。
个人经验:我在一个智能音箱项目里,把系统分区从 ext4 换成 EROFS,启动时间缩短了 2 秒。而且压缩后镜像小了 40%,烧录时间也快了。一举两得。
1.5 架构图:一目了然
下面这张图,是我自己画的。它展示了三层架构的关系,以及数据流的走向。你仔细看看,应该能理解为什么我说「VFS 是路由,FS 框架是调度,具体文件系统是执行」。
1.6 各层职责对比
为了让你更清楚,我整理了一个表格。这样对比着看,一目了然。
| 层次 | 主要职责 | 典型接口/功能 | 我踩过的坑 |
|---|---|---|---|
| VFS 层 | 提供统一文件操作接口 | open(), read(), write(), close() | 路径解析时没处理好符号链接,导致死循环 |
| FS 框架层 | 挂载管理、缓存、权限 | mount(), umount(), page cache | 热插拔时没卸载干净,文件句柄泄漏 |
| 具体文件系统层 | 物理存储读写、格式管理 | FAT: 簇管理;JFFS2: 日志;EROFS: 压缩 | JFFS2 挂载太慢,被客户投诉 |
警告:千万不要在 VFS 层做太多业务逻辑。我曾经见过有人把加密逻辑写在 VFS 的 read 函数里,结果性能暴跌。正确的做法是在 FS 框架层挂钩子,或者直接在具体文件系统层实现。
1.7 小结
好了,这一章就聊这么多。OpenHarmony 的文件系统架构,说白了就是「分层解耦」。VFS 层让你写应用时不用管底层,FS 框架层让你做策略时不用动驱动,具体文件系统层让你换存储时不用改上层。这种设计,我在多个项目里验证过,确实好用。
下一章,我们会深入 VFS 层的核心数据结构。到时候我会拿一个实际项目里的代码,带你一步步分析。嗯,今天就到这里。