昨晚和fumin 聊到数据一致性的时候,他问及什么是数据一致性Consistency,我只能机械的背出数据一致性的概念:所访问的数据是所期望的数据而不是其他数据或者垃圾数据。上午重新翻了《操作系统设计与实现》文件系统这一章,谈到了fsck 所进行的操作,fsck 是类UNIX 操作系统用于数据一致性检查的工具,它进行了以下工作:
首先数据块使用情况:建立两个表,一个是遍历所有所有inode 节点,记录块使用情况,数据块每使用一次在其位置上加一,则n 表示该数据块被使用n 次,0表示没有在使用;二是遍历空闲块链表或者blockmaps 记录所有空闲块的表,1 表示空闲,0 表示不空闲,那么正常情况应如下:
0011001001001 使用中的块
1100110110110 空闲块
所有的块要么不是在使用中,要么就在空闲块中,且只使用一次。数据不一致的情况之一有:
0011001001001 使用中的块
0100110110110 空闲块
第一个块即不在使用中的块,也不再空闲块中,这就浪费了存储空间,修正的方法就是把其添加到空闲块链表或者修改blockmaps。另一种情况是:
0011001001001 使用中的块
2100110110110 空闲块
也就是第一块在空闲块链表中记录了两次(不可能在blockmaps 里面出现这样的情况)。这种情况比较简单,将空闲块链表中多余块删除,更严重的情况:
1011001001001 使用中的块(情况A)
1100110110110 空闲块
2011001001001 使用中的块(情况B)
0100110110110 空闲块
情况A 第一个数据块即在空闲块表中也在使用块表中,如果将这个空闲块分配给新的数据,那么以前的数据就完全被覆盖且无法恢复了,为了避免这种情况的发生,应该将此空闲块从空闲块中删除。情况B 是一个数据块被两个文件所使用,可以复制该数据块内容到新的数据块,并修改对应的一个inode 该块数据地址到新的复制块的地址。
接着在检查完块使用情况后检查链接,每个文件的inode 上会有一个计数器,在文件创建的时候,计数器设置为1,每增加一个该文件的硬链接计数器加1,一般情况下只有该文件的计数器为1的时候才能够删除。在fsck 的过程中会统计每个文件的硬链接的个数,和对应文件的计数器进行比较,可能出现以下几种不一致的情况:
1、硬链接数目小于计数器值,这样即使所有硬链接都删除了,该文件也不能删除
2、硬链接数目大于计数器值,问题较严重,以后可能导致硬链接指向了被重新分配内容的区域(发生了不一致性)。
两种通过实际的硬链接数进行修改为正确的值即可。