问题描述
如果在物理磁盘中出现了坏块,那么使用该坏块的文件将无法正常读取(比如在复制时会显示I/O错误)。那么我们该如何定位受坏块影响的文件呢?
本文将通过一系列方法在文件系统中找到受坏块影响的文件。
注意事项
进行坏块检测是文件系统无关的,而文件定位是文件系统相关的。所以,不同文件系统要使用不同处理工具。例如,在ext2/ext3/ext4中使用debugfs命令,而其他的文件系统要使用其他工具。
针对磁盘操作具有一定的危险性,注意数据备份!!!
本文内容是对「archlinux/Identify damaged files」的学习与整理,并未进行实际操作与验证。我们的目的是了解”查找受坏块影响的文件的“方法。
环境概述
本文是针对Ext4文件系统。
确定文件系统的块大小
使用tune2fs命令确定文件系统块大小:
#!/bin/sh tune2fs -l /dev/sdxy | grep -i Block
找到文件系统的坏块值
你可能已经使用badblock命令找到坏块值,但是该值不一定是文件系统坏块值。这是由于badblock命令所使用的块大小,与文件系统的块大小不同(或者说不一定相同)。所以有以下两个选择。
使用相同块大小
#!/bin/sh badblock -b "<file system block size>" -v /dev/sdxy
该命令扫描特定分区,并且使用文件系统块大小,所以输出的坏块位置即是文件系统中的坏块值。
使用不同块大小
如果已经使用badblock扫描磁盘,但是扫描时的块大小并不是文件系统的块大小,则需要进行转换:
original block number * badblocks_block_size / filesystem_block_size
上面的两个公式是等价的,都基于「相同位置 = 块位置 x 块大小 = 文件系统块大小 * 文件系统块位置」这一点。
开始文件系统调试
进入debugfs交互模式
执行debugfs命令,进入debugfs的交互模式:
# debugfs debugfs 1.45.4 (23-Sep-2019) debugfs: open /dev/sdxy ncheck inodenumber
打开分区
在debugfs的交互模式中,使用open命令打开分区:
debugfs: open /dev/sdxy
获取特定块的信息
然后,使用debugfs的testb命令获取坏块的信息:
debugfs: testb <blocknumber>
!!!将<blocknumber>替换为前面得到的坏块值。
如果debugfs提示块未被使用,则表示该块出于空闲状态。也就是说,目前没有文件被该块损坏。这是一个好消息。
获取inode值
如果debugfs提示块已被使用,则需要使用如下命令获取对应的inode值:
debugfs: icheck <blocknumber>
该命令将会返回两个值:「块值」与「inode值」。
获得文件名(最终步骤)
debugfs: ncheck <inodenumber>
将<inodenumber>替换为上面icheck输出的第二个值。
例外情况
如果inode非常小并且ncheck无法返回文件名,那么可能是日志(journal)本身损坏。通过运行下面命令删除日志:
#!/bin/sh tune2fs -O ^has_journal /dev/sdxy
再次运行testb命令:
debugfs: testb <blocknumber>
如果确实被日志使用,由于前面清除动作,则上述命令执行后应该提示块未被使用。
构建新的日志:
#!/bin/sh tune2fs -j /dev/sdxy
参考文献
archlinux/Identify damaged files
Find which files are affected by bad blocks on ext4 filesystem