Linux EXT4磁盘损坏:为什么只读(ro)能挂载、读写(rw)彻底失败?数据抢救原理与实操指南
一、问题背景(完全对应本次故障场景)
本次故障发生在 VMware 虚拟机异常崩溃之后,表现为:
-
EXT4 文件系统出现脏数据、日志中断、部分扇区损坏
-
系统自动挂载为读写模式时,持续出现 Input/output error
-
大量内核驱动文件读取失败(vidtv 目录批量报错)
-
执行
mount -o remount,ro在线切换只读失败 -
只要是读写模式就持续报错、损坏扩大,只读模式可稳定读取剩余数据
很多人疑惑:为什么磁盘坏了,只读能正常用,读写直接崩?
这不是 bug,是 Linux EXT4 文件系统核心保护机制,也是数据抢救的唯一正确逻辑。
二、核心原理:ro 安全、rw 致命的根本原因
1. 崩溃后的文件系统状态:脏文件系统(Dirty Journal)
VM 强制崩溃、异常断电、磁盘IO中断,会导致 EXT4 的 日志(Journal)没有正常收尾。
正常关机:系统写完日志、标记文件系统为「干净」。
崩溃关机:日志写到一半中断,文件系统被内核标记为 Dirty 脏状态、元数据不一致。
2. 读写(rw)挂载 = 强制修复日志(会二次毁盘)
EXT4 默认规则:只要以读写模式挂载脏文件系统,内核必须先回放日志、补全未完成事务。
日志回放 = 大量写入操作。
而你的磁盘已经存在:
-
物理坏扇区
-
文件块损坏
-
inode 读取失败
结果就是:内核尝试写入修复 → 碰到坏块写入失败 → 文件系统彻底紊乱 → 更多文件损坏、I/O 报错爆炸式增加。
这也是 Linux 内核默认策略 errors=remount-ro 的意义:检测到损坏立刻切只读,阻止写入继续破坏数据。
3. 只读(ro,noload)挂载 = 禁止一切写入、跳过危险修复
关键参数 ro,noload 的核心作用:
-
ro:全程只读,不修改任何磁盘数据
-
noload:不加载、不回放、不修复损坏的 journal 日志
等于告诉内核:不要修、不要改、只读取现存有效数据。
因此哪怕文件系统破损、有坏块、日志损坏,依然可以稳定挂载,安全读取未损坏文件。
三、为什么不能在线 remount 只读?(你报错的真正原因)
你执行:
mount: cannot mount ... read-only
原因:
已经被系统自动挂载为 rw 脏状态的分区,禁止在线切换只读。
内核规则:脏文件系统正在运行读写事务,无法动态切换保护模式。
必须:完全卸载 → 重新手动只读挂载。
四、I/O Error 报错本质:不是系统坏了,是扇区物理损坏
你大量报错:
Cannot open: Input/output error
代表:这些文件所在的磁盘扇区已经物理损坏,内核无法读取。
重点结论:
-
坏文件 = kernel-5.10/drivers/media/test-drivers/vidtv 测试驱动目录
-
该目录与 RK3562 安卓编译、工控项目完全无关
-
删除/跳过该目录,不影响项目完整性、不影响编译
五、正确的数据抢救标准流程(本次故障专用)
1. 终止自动读写挂载(关键)
Ubuntu 桌面自动挂载默认是 rw 模式,极其危险。
操作:
-
退出源码目录:
cd ~ -
杀掉占用进程:
sudo fuser -k -m /挂载点 -
卸载分区:
sudo umount /挂载点
卸载失败直接重启,开机绝对不要点击文件管理器磁盘图标,杜绝自动rw挂载。
2. 通过UUID精准挂载(杜绝盘符漂移)
查询损坏分区UUID:
blkid | grep 你的UUID
安全只读挂载命令:
sudo mount -o ro,noload UUID=xxx /mnt/recover
3. 打包备份:跳过损坏目录,保留全部有效源码
使用 exclude 规避坏块目录,彻底消除I/O报错,完整备份可用工程代码:
sudo tar --preserve-permissions --preserve-links -zcvf /tmp/rk3562_backup.tar.gz \ --exclude="./out" \ --exclude="./rockdev" \ --exclude="./IMAGE" \ --exclude="./kernel-5.10/drivers/media/test-drivers/vidtv" \ .
六、绝对不能做的高危操作(避坑重点)
-
禁止带病 rw 挂载操作:会持续扩大坏块范围
-
禁止提前执行 fsck / e2fsck 修复:会直接删除损坏扇区对应的文件,永久丢数据
-
禁止反复读写、编译、解压:加重磁盘物理损伤
唯一正确顺序:先只读备份所有可用数据 → 再尝试修复磁盘。
七、总结一句话核心
EXT4 磁盘损坏后,读写模式会主动修盘、越修越坏;只读模式只读不写、零风险保数据。
Linux 只读不是限制,是内核最后的数据熔断保护机制,是拯救源码的唯一生路。
八、延伸关键结论:Android 编译必须用固态硬盘(SSD),严禁机械硬盘(HDD)
结合本次磁盘IO卡顿、分区损坏、编译报错的全套故障,延伸出嵌入式安卓开发的硬性硬件准则:Android 系统源码编译、Linux 内核编译,只能用固态硬盘,绝对不建议、甚至禁止使用机械硬盘。这也是你本次出现"一股子一股子IO波动、文件系统损坏、虚拟磁盘崩溃"的核心底层硬件诱因之一。
1、安卓编译的IO特性:海量小文件、高频随机读写
Android 源码、Linux kernel 源码具备一个核心特点:文件数量极多、碎片化极强,整个工程包含数十万级别的头文件、源码文件、配置文件、编译缓存。编译过程中会持续产生:高频随机读取、频繁写入缓存、增量覆盖文件、临时文件创建销毁等操作。
这一过程完全适配固态硬盘的工作机制,却是机械硬盘的致命短板。两种硬盘的核心工作逻辑差异,直接决定编译体验与磁盘稳定性:
-
固态硬盘(SSD):无机械结构,随机读写速度快、延迟极低,持续吞吐平稳,应对海量小文件读写无压力,全程无卡顿、无IO脉冲波动
-
机械硬盘(HDD) :依靠磁头、盘片机械转动读写,随机读写速度极差、响应延迟极高,处理海量碎片化文件时,磁头频繁寻址,直接出现"读写卡顿、吞吐断断续续"的一股子波动现象
2、机械硬盘编译的三大致命问题(完全对应你的故障)
(1)IO 波动剧烈,虚拟机极易崩溃
你此前遇到的 VMware 崩溃、disk error while paging、磁盘一股子卡顿,根源之一就是机械硬盘承载虚拟机+安卓编译双重压力。机械硬盘的IO响应延迟过高,虚拟机磁盘队列阻塞,Windows 系统会判定磁盘超时,直接触发虚拟磁盘读写异常,最终导致EXT4文件系统脏数据、日志中断、分区损坏。
(2)磁盘休眠加剧故障恶性循环
机械硬盘自带节能休眠机制,编译过程中短暂空闲就会进入休眠,再次触发读写时需要重新唤醒,产生明显停顿。这种"休眠-唤醒-爆发读写"的循环,就是你感知到的一股子一股子读写,反复的IO中断会持续损伤文件系统,极易造成文件区块损坏。
(3)编译耗时翻倍,开发效率极低
小型代码编译差异不明显,但完整 Android13、RK3562 全量编译差异极大:SSD 全量编译仅需数十分钟,机械硬盘往往需要数小时,且中途极易因IO超时出现编译中断、缓存损坏、任务失败,反复重试进一步加重磁盘负担。
3、为什么虚拟机编译对硬盘要求更高?
你使用的 VMware 动态扩容 vmdk 虚拟磁盘,本身就存在IO损耗:编译时需要持续扩容虚拟磁盘、分配磁盘簇、同步宿主与虚拟机文件数据。这种机制叠加机械硬盘的低IO性能,会形成双重卡顿,不仅拖慢编译速度,更是文件系统损坏、源码读写报错的核心诱因。
固态硬盘的低延迟、稳吞吐,能完美抵消虚拟磁盘的性能损耗,保障编译过程稳定无中断。
4、开发硬件硬性标准(安卓/嵌入式编译专用)
-
必备硬件:全程使用 SATA/NVMe 固态硬盘,优先 NVMe 高速固态,IO延迟更低、稳定性更强
-
禁用硬件:机械硬盘绝不用于存放虚拟机文件、安卓源码、编译工程,仅可用于存放成品固件、备份文件
-
避坑要点:移动机械硬盘、老旧低速固态、U盘,均不支持源码编译,极易出现IO错误、文件损坏
5、总结
本次 EXT4 磁盘损坏、IO 报错、虚拟机崩溃,并非单纯的系统操作问题,机械硬盘承载安卓源码编译的硬件错配,是核心底层诱因 。Android 编译是典型的高强度IO负载场景,固态是刚需,机械是隐患,后续所有嵌入式编译开发,必须以固态硬盘为基础,才能从根源避免文件损坏、编译崩溃、数据丢失等问题。