文件系统检查FSCK基本过程解析

最近一直在熟悉e2fsck的实现过程,为后续快速fsck在用户态的实现做点准备。源码功能细节部分暂时就不贴了,可能多数人也并不关心,将文档基本功能部分分享给大家。

2.1        工具基本结构组成

2.1.1       Pass 1:inode表的检查

检测整个文件系统中的inode, 主要检查以下内容

1)        Inode的mode  field是否合法;

2)        Inode 记录的size和块计数(blockcount)是否正确;

3)        对于device fifo或socket其 size应该为0,如果没有记录则直接置0再写回。

4)        数据block是否有被其他的inode引用(不允许出现);

5)        收集以下信息数据,主要是方便后续其它过程不再读取inode:

inode_used_map:已使用的inode的bitmap
inode_dir_map: 记录的是目录的inode的bitmap

inode_reg_map:记录的是普通文件的inode的bitmap(reg 指regular)

inode_bad_map:记录中出现bad field的inode 的bitmap

inode_bb_map: 记录的是坏块的inode 的bitmap

inode_imagic_map:记录的是imagic的inode的bitmap

block_found_map:已使用的block的bitmap

block_dup_map:被多个inode使用的block

dir_map: 目录inode 的数据块(data block)
备注:如果后续查出不一致性,还是需要读取inode来修复。

2.1.2       Pass 1b:处理block被 多个inode使用的异常

主要由三个过程,可简单称为:pass1B pass1C pass1D三个过程。

1)        Pass1B:扫描所有的inode 的数据block。产生一个记录被重复使用的block及引用他们的inode的列表;

2)        Pass1C:遍历文件的树形结构,决定这些inode的父目录。以此来显示那些涉及到的inode的路径名;

3)        Pass1D: 主要是修复过程,对重复引用了数据块的 inode,决定用户来clone出文件的复本,或者直接将重复的部分直接删除。

 

2.1.3       Pass2:检查目录结构

主要检查以下几项:

1)        目录项(entry, rec_len)应该至少是8个字节,并且不能大于当前的目录块中的剩余空间大小;

2)        目录表项中的名字长度 (name_len)应该小于 rec_len – 8;

3)        在目录表项中的inode 号应该在合法的边界内;

4)        Inode号应该指向一个已使用的inode;

5)        第一个表项应该是’.’(当前目录),且它的inode应该就是本目录所在的inode;

6)        第二个表项应该是‘..’(父目录)

7)        收集各个目录的子目录所在的inode号。

为了缩减fsck的时间,目录块的处理是按照块号来有序处理的。

事实上,此过程的进行需要依赖于第一步中的数据,主要包括几个位图:

*      -The directory information collected in pass 1.

 *   - The inode_used_map bitmap

 *   - The inode_bad_map bitmap

 *   - The inode_dir_map bitmap

过程2中会释放以下结构:

*      -The inode_bad_map bitmap

 *   - The inode_reg_map bitmap

        

2.1.4       Pass3:检查目录的连接

此过程主要是确保所有目录都已连接到文件系统的树形结构上,其实现的基本算法如下所示:

1)        检查根目录是否存在,如果没有则创建一个新的,并标记此新的根目录为done;

2)         遍历所有的目录的inode。对每个目录均利用dirinfo.parent 来在整个文件系统树中回溯,直到找一个被标记为done的目录为止,如果找不到,那么这个目录会被断开连接, e2fsck 会将其重连接到/lost+found目录。此外,如果在回溯的过程中,两次遇到同一个目录,则意味着这是一个环,同样也会将此目录断开,重连接到/lost+found目录。

3)        Pass3还包括了子程序e2fsck_reconnect_file(),它是用来连接inode到/lost+found目录的,这会在pass4中被调用。而且,e2fsck_reconnect_file()会调用 get_lost_and_found(),以保证在没有/lost+found目录时,创建这一目录。

4)        会被释放的数据结构:The dirinfo directory information cache

 

2.1.5       Pass4:检查引用计数

Pass4主要是检查引用计数,此过程会释放以下两个位图:

inode_bb_map(bad block)和inode_imagic_map

事实上大部分的inode的引用计数应该为0(没有分配的inode),多数的文件或目录的引用计数为1。只有少数的文件的引用计数才会大于1,主要是一些文件或目录被链接到多个目录。

         程序中使用一个inode的bitmap来标记那些引用的次数为1的inode。对于那些大于1的,我们使用一个有序的list来记录他们的引用计数。此外还用一个可选的bitmap来标记那些在有序的list中的node,这一占烛用来加速pass2。Pass 2 increments inode counts as it finds them,* so this extrabitmap avoids searching the sorted list to see if a

 *particular inode is on the sorted list already.

 

2.1.6            Pass5:检查block和inode的位图

主要是基于diskbitmap做检查,校验block 和inode的bitmap。

你可能感兴趣的:(linux)