读书人

(莱昂氏unix源代码分析导读-39)inod

发布时间: 2013-01-05 15:20:39 作者: rapoo

(莱昂氏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块开始的(#0块UNIX忽略不用、“超级块”占据了磁盘的#1块);

2) 每个块可容纳16个inode

(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变为0)inode所指向的物理文件。

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

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

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

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

(3) itrunc ——删除文件;

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

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

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

读书人网 >UNIXLINUX

热点推荐