Linux内核文件系统new_block函数理解

来源:互联网 发布:百胜软件电话 编辑:程序博客网 时间:2024/05/04 00:36

这几天在看赵炯的Linux内核完全注释版(修正版v1.9.5一书),其中很多知识较难理解,为加深理解且防止忘记,在这里将已理解部分记载下来,当然我自己理解的并一定就是正确的,甚至还有很多错误,如果有某位大神能看到我这篇博客并能指出其中的错误,我将十分感谢,废话不多说了,先上代码

int new_block(int dev)
 76 {
 77     struct buffer_head * bh;
 78     struct super_block * sb;
 79     int i,j;
 80 
 81     if (!(sb = get_super(dev)))
 82         panic("trying to get new block from nonexistant device");
 83     j = 8192;
 84     for (i=0 ; i<8 ; i++)
 85         if (bh=sb->s_zmap[i])
 86             if ((j=find_first_zero(bh->b_data))<8192)
 87                 break;
 88     if (i>=8 || !bh || j>=8192)
 89         return 0;
 90     if (set_bit(j,bh->b_data))
 91         panic("new_block: bit already set");
 92     bh->b_dirt = 1;
 93     j += i*8192 + sb->s_firstdatazone-1;
 94     if (j >= sb->s_nzones)
 95         return 0;
 96     if (!(bh=getblk(dev,j)))
 97         panic("new_block: cannot get block");
 98     if (bh->b_count != 1)
 99         panic("new block: count is != 1");
100     clear_block(bh->b_data);
101     bh->b_uptodate = 1;
102     bh->b_dirt = 1;
103     brelse(bh);
104     return j;
105 }

此函数位于Linux/fs/bitmap.c文件中,代码前面的数字是其在文件中的行数,这里先对变量 i 和 j 进行解释,i为一个下标索引,是s_zmap的小标,s_zmap是一个数组,长度为8

存放着buffer_head的指针,儿buffer_head结构体中有逻辑块位图的起始地址,故可以推断出总共有8个逻辑块位图块。

j是在一个逻辑块位图块的bit偏移值,注意,不是字节偏移,因为一个逻辑块大小为1k,所以j的大小不能超过1024*8=8192。

 84     for (i=0 ; i<8 ; i++)
 85         if (bh=sb->s_zmap[i])
 86             if ((j=find_first_zero(bh->b_data))<8192)
 87                 break;

这里是要从8个逻辑位图块搜索,寻找首个为0的比特位,如果搜索完还找不到则退出,若找到i为首个比特位为0在第i个逻辑位图块中,偏移的bit数为j

 93     j += i*8192 + sb->s_firstdatazone-1;
 94     if (j >= sb->s_nzones)
 95         return 0;

首先要知道一个逻辑位图块的一个bit为对应一个逻辑块,即1k空间,从前面知道首个bit为0位在第i个逻辑位图块中,j为第i个块的偏移bit数,故(i*8192)+j为首个为0

的bit为对应的逻辑块在block区的偏移逻辑块数,而sb->s_firstdatazone为block区首地址对存储设备的第一逻辑块的偏移逻辑块数,注意,不是字节数,也不是bit数,而是逻辑块数。

其他部分书中都讲的比较清楚,如果忘记了请记得回头看书



                                                            73,1          50%

0 0