我有控制台访问embedded式Linux设备。 该设备的闪存部分被分区为FAT文件系统。
它运行的是linux-2.6.31。
不过,我在控制台上看到这些错误,FAT文件系统变成只读。
111109:154925 FAT: Filesystem error (dev loop0) 111109:154925 fat_get_cluster: invalid cluster chain (i_pos 0) 111109:154925 FAT: Filesystem error (dev loop0) 111109:154925 fat_get_cluster: invalid cluster chain (i_pos 0)
我不明白为什么会发生这种情况? 根源是什么? 什么是修复? 我将不胜感激的答案,可以指出我如何调查在设备上可能的根本原因这个问题。
实际上在比特和字节级发生的是文件分配表的4个字节(或更多)已被0x00
字节覆盖。
我将简要地解释文件分配表的工作原理。 它可能被看作是一个数组,其值是同一个数组的索引。 因此,如果我们知道文件的第一个簇号是i
,那么下一个簇号是fat[i]
,接下来的是fat[fat[i]]
,依此类推。 (这是略有简化)。 为了表示已达到链的末端,使用特殊的EOC值而不是有效的簇号。
要从磁盘读取FAT文件,您需要按顺序存储文件所在的簇编号。 目录条目给出了第一个簇号( i
)。 其余的可以在链式fat[i]
, fat[fat[i]]
等中find,直到遇到EOC值。 然后,从集群号码获取每个集群的磁盘位置,将每个集群读入内存并连接起来,这是一个简单的计算。
当在这样的链之后find值0x00000000
时,发生fat_get_cluster: invalid cluster chain
error。 这不应该发生。 它应该是新的有效簇号或EOC值。 发生这种情况时不能再读取该文件,因为没有办法进一步跟踪链。 ( 0x00000000
值用于将群集标记为空闲,群集0
永远不用于存储数据,因此没有歧义)
你的情况可能是一个特殊的情况,因为i_pos
被赋予了0.当我收到这个消息的时候,它是一个很大的数字。 内核源码说:
loff_t i_pos; /* on-disk position of directory entry or 0 */
所以i_pos不是一个簇号,而是磁盘上的一个位置。 什么意思,当它是零,我不知道。
编辑:至于什么可能造成的,我只能推测,但这里有一些可能性:
dd if=/dev/zero of=/dev/sda1 bs=512 count=1 seek=32
– 不要在家试试! FAT文件系统驱动程序实际上保持两个FAT表最新的冗余,第二个躺在第一个之后 。 检查它们是否相同可能会给发生的事情提供线索。 如果他们只是破坏集群链的价值不同,那么我认为,由于至less有1个和3个“适当”的工作,所以它会以某种forms直接篡改。
然而,我认为大多数现代驱动程序似乎可能将整个FAT表保存在RAM中,并将更改的部分写回到两个驱动器副本。 因此,即使有一次有差异,在正常使用过程中,它可能已经被迅速和默默地“固定”了。 请注意,这只是一个受过教育的猜测。
最后,如果没有关于情况的进一步的信息,就很难确定地知道,即使这样,也很可能是猜测。 理想的情况下,如果你能够可靠地重现这个问题。 然后,我会比较“之前”和“之后”的FAT表(和FAT头),看看究竟发生了什么变化,以及寻找变化的位置和内容提示。
您的FAT32由于某种原因已被损坏。 我的USB棒通常最终会损坏FS,因为我目前正在ARM平台上debuggingUSB主机问题。 经过我的testing,我从桌面机器(Ubuntu 11.04)发出以下命令:
$ sudo fsck.msdos -aw /dev/sdb1
参考: https : //askubuntu.com/questions/31614/how-to-delete-edit-files-from-readonly-filesystem
你得到的错误集群链和文件系统错误清楚地表明它是文件系统错误。
维基百科进入FAT说:
分区被分成相同大小的簇,连续空间的小块。 簇大小根据所使用的FAT文件系统的types和分区的大小而不同,通常簇大小介于2 kB和32 KB之间。 每个文件可能会占用这些集群中的一个或多个,具体取决于其大小; 因此,文件由这些簇的链表示(称为单链表)。 但是,这些群集不一定相邻存储在磁盘的表面上,而是通常在整个数据区域中被分割。
文件分配表(FAT)是映射到分区上的每个群集的条目的列表。 每个条目logging五件事情之一:
- 链中下一个集群的集群编号
- 群集链(EOC)条目的特殊结尾,指示链的结尾
- 标记坏簇的特殊条目
- 一个零表示该集群未被使用
这个链接说有人用fsck解决了与存储卡类似的问题。