下面是mkfs命令的一个例子
mkfs /dev/hd6 60000
结果:
20000个inodes,60000个blocks,第一个数据块块号为638
指导思想:
不看源代码的话,格式化一个文件系统,应该改变的是:
(1),文件系统的超级块信息,需要用户输入的块的总数算出i节点的个数和i节点位图块的个数和逻辑块位图块的个数及第一个数据块的块号。setup_tables()函数完成这个任务。
(2),建立根目录,需要申请一个数据块,需要申请一个根目录对应的i节点,是文件系统中的第一个节点。
修改根目录对应的i节点在i节点位图中对应的位和根目录所在的块对应的逻辑块位图中的位。
make_root_inode();函数完成这个任务。
(3)源程序里还有第三个任务,就是统计磁盘分区中坏块的数目,并把所有的坏块看成一个坏块文件,这个坏块文件对应第二个节点。make_bad_inode()函数完成这个任务。
思路分析:
main()函数首先取得用户给出的块数放到BLOCKS里。
然后调用setup_tables()函数,setup_tables()函数的作用是根据块数算出i节点的总数既块数的三分之一。
然后算出i节点位图的块数和逻辑块位图的块数,还有第一个数据块的块号。
然后把逻辑块位图块清零(范围是数据区对应的位图既FIRSTZONE之后的块对应的位)和把i节点位图块清零(第一个位没有清零,第一个位对应根节点)。然后初始化了i节点缓冲区。最后打印出超级块信息。
区块的数目ZONES既块数BLOCKS为60000,INODES的数目为块数的三分之一既20000。
i节点位图的块数IMAPS为3。
#define NORM_FIRSTZONE (2+IMAPS+ZMAPS+INODE_BLOCKS)
NORM_FIRSTZONE数目既数据区前面的块数。
ZMAPS = 0;
while (ZMAPS != UPPER(BLOCKS - NORM_FIRSTZONE,BITS_PER_BLOCK))
ZMAPS = UPPER(BLOCKS - NORM_FIRSTZONE,BITS_PER_BLOCK);
逻辑块位图的块数ZMAPS为8。
FIRSTZONE = NORM_FIRSTZONE;
这时FIRSTZONE为2+3+8+(20000/32)=2+3+8+625=638
所以第一个数据块的块号FIRSTZONE为638。
问题1:为什么setup_tables()函数开始要把zone_map[]数组都置位?
static char zone_map[BLOCK_SIZE * Z_MAP_SLOTS];
memset(zone_map,0xff,sizeof(zone_map));
因为开始不知道FIRSTZONE的大小,需要计算,计算完了之后再清零。
意思是数据区前面的块都已经使用了。
当然也可以不用先置位再清零。算出FIRSTZONE之后直接把数据区之前的应用mark_zone()函数也可;
问题2:为什么i节点的总数和块的总数是1:3的关系,这个也可以是1:4。