想象一下当单个设备 Btrfs 上的文件损坏时的情况。在这种情况下,需要按原样包含损坏的位的文件内容。
正如 mount 的手册页中所述:
nodatasum
Enable/disable data checksumming for newly created files.
所以它在读取文件时不会禁用校验和检查。
我猜想所有涉及文件系统读取的标准系统调用都会在这个文件上失败。原始磁盘读取不是一个选项,因为可能会出现碎片。
当我尝试cat
此类文件时,出现错误:
cat: file: Input/output error
dmesg
报告如下消息:
[631847.884641] BTRFS warning (device loop0): csum failed ino 257 off 0 csum 1280268577 expected csum 2391276770
知道损坏发生在 处off 0
,因此这是文件的前 4096 字节,实际上我能够非常轻松地检索未损坏的块:
dd if=file bs=4K skip=1
顺便说一句,将数据写入和附加到损坏文件的未损坏块也会成功。至少当只有一个损坏的块并且不是最后一个时。起初它让我感到惊讶,但后来我认为这可能是一个很好的功能,这样必须附加关键数据的应用程序就不会卡在损坏的文件上。
问题是如何从损坏的块(或整个损坏的文件)中检索数据?
答案1
作为最后的手段,你可以尝试
btrfs 检查 --init-csum-tree /tmp/copy_of_the_device.bin
此命令将更改文件系统,结果可能比以前更糟糕,因此仅在文件系统的 dd 或 ddrescue 副本上运行此命令。
答案2
Linux Kernel 5.11 引入了挂载和忽略文件校验和的选项。这将允许复制出错误 csum 的数据。
mount -o rescue=ignoredatacsums /dev/sdX /mnt
如果文件损坏程度最低并且您有某种奇偶校验,这可以让您完全恢复文件,例如2杆