(莱昂氏unix源代码分析导读-39)inode“资源”的获取和释放

                                              by cszhao1980

iget()函数用于获取inode资源,它有2个参数,设备号和inode id。前面说过,通过这两个参数

会唯一确定一个inode。简单的说,该函数的作用就是将指定的磁盘inode读入内存inode数组,

Lock该项(即会设置 ILOCK flag),它返回一个指向该inode数组项的指针。

 

事实上,iget()做的更多一些,它首先检查内存inode数组中,如果该inode项已经在其中,则直

Lock并返回。只有此inode尚未读入时,才需要从磁盘上读取。

 

莱昂对此函数的讲解比较详细,在这里我只说几点:

(1)    在读入该磁盘inode所在盘块时,使用如下语句:

7319:     ip = bread(dev, ldiv(ino+31,16));

1)   indoe块是从#2块开始的(#0UNIX忽略不用、“超级块”占据了磁盘的#1块);

2)   每个块可容纳16inode

 

(2)     在将磁盘inode内容复制给内存inode时,利用了二者自“i_mode”起layout相同的特点。

     因此,只需将指针指向磁盘inode头,逐个字节拷贝即可。如下所示:

7328:     ip1 = ip->b_addr + 32*lrem(ino+31, 1)

7329:     ip2 = &p->i_mode;

7330:     while(ip2 < &p->i_addr[8])

7331:          *ip2++ = *ip1++;

 

3  它会增加该inode的引用计数(i_count)。这也正是main()函数两次调用它的原因,

       否则,在1618行,直接将rootdir赋值给u.u_cdir即可。代码如下所示:

 

0106: #define ROOTINO 1     //根目录inode#1号磁盘inode

1616:     rootdir = iget(rootdev, ROOTINO);

1617:     rootdir->i_flag =& ~ILOCK;

1618:     u.u_cdir = iget(rootdev, ROOTINO);

1619:     u.u_cdir->i_flag =& ~ILOCK;

 

iput(p)函数用于释放inode资源,它只有一个参数,即要释放的inode。乍一想,这个函数应该很简单,

iget的“逆”操作就可以了:

(1)         i_count减一;

(2)         ILOCK标志

(3)         i_count变为0,则释放其占用inode数组项。

 

但事实上,该函数要复杂的多:

(1)         程序在获取inode资源后,可能因某种原因修改了inode

(2)         甚至可能需要删除(文件的硬链接i_nlink变为0inode所指向的物理文件。

 

因此,这两种情况也需要处理。理解了这些,这个函数就显得很简单了。

它内部还调用了其他几个函数,介绍如下:

(1)         prele ——清除ILOCK标记,唤醒因此睡眠的进程;

(2)         iupdat ——将更新的inode写入磁盘;

(3)         itrunc ——删除文件;

(4)         ifree ——回收inodefile system的空闲inode数组(将来会谈到)。

 

博客地址:http://blog.csdn.net/cszhao1980

博客专栏地址:http://blog.csdn.net/column/details/lions-unix.html

 

你可能感兴趣的:((莱昂氏unix源代码分析导读-39)inode“资源”的获取和释放)