linux-0.11调试教程,mkfs.c源代码分析(1)

来源:互联网 发布:iphone 拍电影软件 编辑:程序博客网 时间:2024/05/19 09:09


下面是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

所以第一个数据块的块号FIRSTZONE638


void setup_tables(void)
{
    int i;

    memset(inode_map,0xff,sizeof(inode_map));
    memset(zone_map,0xff,sizeof(zone_map));
    memset(super_block_buffer,0,BLOCK_SIZE);
    MAGIC = SUPER_MAGIC;
    ZONESIZE = 0;
    MAXSIZE = (7+512+512*512)*1024;
    ZONES = BLOCKS;        /*BLOCKS为60000 */
/* some magic nrs: 1 inode / 3 blocks */
    INODES = BLOCKS/3;        /* INODES为20000 */
/* I don't want some off-by-one errors, so this hack... */
    if ((INODES & 8191) > 8188)
        INODES -= 5;
    if ((INODES & 8191) < 10)
        INODES -= 20;
    IMAPS = UPPER(INODES,BITS_PER_BLOCK);
    ZMAPS = 0;
    while (ZMAPS != UPPER(BLOCKS - NORM_FIRSTZONE,BITS_PER_BLOCK))
        ZMAPS = UPPER(BLOCKS - NORM_FIRSTZONE,BITS_PER_BLOCK);
    FIRSTZONE = NORM_FIRSTZONE;
    for (i = FIRSTZONE ; i<ZONES ; i++)
        unmark_zone(i);
    for (i = ROOT_INO ; i<INODES ; i++)
        unmark_inode(i);
    inode_buffer = malloc(INODE_BUFFER_SIZE);
    if (!inode_buffer)
        die("Unable to allocate buffer for inodes");
    memset(inode_buffer,0,INODE_BUFFER_SIZE);
    printf("%d inodes\n",INODES);
    printf("%d blocks\n",ZONES);
    printf("Firstdatazone=%d (%d)\n",FIRSTZONE,NORM_FIRSTZONE);
    printf("Zonesize=%d\n",BLOCK_SIZE<<ZONESIZE);
    printf("Maxsize=%d\n\n",MAXSIZE);
}

问题1:为什么setup_tables()函数开始要把zone_map[]数组都置位?

static char zone_map[BLOCK_SIZE * Z_MAP_SLOTS];


    memset(zone_map,0xff,sizeof(zone_map));


因为开始不知道FIRSTZONE的大小,需要计算,计算完了之后清零。

    for (i = FIRSTZONE ; i<ZONES ; i++)
        unmark_zone(i);


意思是数据区前面的块都已经使用了。

当然也可以不用先置位再清零。算出FIRSTZONE之后直接把数据区之前的应用mark_zone()函数也可;

问题2:为什么i节点的总数和块的总数是1:3的关系,这个也可以是1:4