nas因btrfs元数据损坏进入只读状态时,须先以root身份确认设备路径与只读原因,再通过dmesg定位csum异常,用btrfs-find-root扫描候选tree root,验证后以usebackuproot只读挂载或btrfs restore导出数据,严禁使用--repair。

当NAS因Btrfs元数据损坏突然进入只读状态,系统拒绝写入、快照失效、共享文件夹无法访问,必须立即执行非破坏性诊断与定位,避免误用repair参数引发二次损毁。
确认Btrfs设备路径与只读原因
在Ubuntu Live或已安装的Linux系统中以root身份运行:sudo -i。这一步不可跳过,后续所有命令依赖root权限。
执行 cat /proc/mdstat 查看软RAID状态;若为SHR或LVM封装,则追加运行 lvs 和 pvs。关键识别出真实Btrfs设备路径,例如 /dev/mapper/vg1-lv1 或 /dev/md3 —— 错误地选成/dev/sdb这类物理盘会直接导致操作失败。
运行 dmesg | grep -i "btrfs\|csum\|tree root",重点捕获类似 "BTRFS error (device dm-1): level verify failed on logical 32899072, mirror 1, wanted 0, found 1" 的日志。该输出明确指向元数据树层级错乱,是典型csum item异常触发的只读保护,此时文件系统尚未崩溃,仍可读取。
定位可用tree root并验证有效性
使用只读模式扫描所有潜在根节点:btrfs-find-root -t 0 /dev/md3 &> /tmp/roots.log(将/dev/md3替换为上步确认的实际设备)。该命令不写盘、不改动任何数据,但耗时较长,需耐心等待15~40分钟。
扫描完成后,用 cat /tmp/roots.log | grep "Well block" 提取全部候选root位置。输出形如:Well block 32899072 gen 123456789。注意:gen值越高,代表该root越接近崩溃前最新状态,应优先尝试。
对每个候选block,运行验证命令:btrfs check --tree-root 32899072 --super 0 /dev/md3。若返回末尾出现 "found tree root at 32899072" 且无ERROR字样,说明该root可用;若报 "open_ctree failed: -5" 或 "bad tree block",则换下一个gen值更低的block继续试。此过程严禁添加 --repair 参数。
挂载恢复并导出数据
方法一:直接只读挂载(最快)
创建挂载点:mkdir -p /mnt/recover;执行:mount -t btrfs -o ro,usebackuproot,commit=0,subvol=/ /dev/md3 /mnt/recover。其中 usebackuproot 强制使用上步确认的有效tree root,commit=0 禁用写缓存,规避元数据再校验失败风险。
方法二:用btrfs restore提取文件(更安全)
运行:btrfs restore -D -i -v /dev/md3 /mnt/export。-D启用dry-run仅列出可恢复文件,确认路径无误后删掉-D,改用 btrfs restore -i -v /dev/md3 /mnt/export 开始实际拷贝。该命令自动跳过损坏inode,保留原始权限与时间戳,但不会恢复快照和子卷结构。
方法三:强制读写挂载(仅限紧急覆盖写入)
若必须临时写入修复日志或配置,使用:mount -t btrfs -o rw,usebackuproot,skip_balance,flushoncommit /dev/md3 /mnt/fix。注意:此模式下任何写操作都可能加剧元数据混乱,完成即刻umount,不可长期挂载。











