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