by cszhao1980
一个设备被mount进系统后,就被称为一个文件系统。它有两类资源:
(1) 磁盘inode资源;
(2) 普通盘块资源。
对于inode资源,unix v6采用了一种很简单的管理方法。即在超级块中维护一个free inode
资源数组(max 100 entry),存放可用的inode资源(inode id):
5568: int s_ninode; /* number of in core I nodes (0-100) */
5569: int s_inode[100]; /* in core free I nodes */
5571: char s_ilock; /* lock during I list manipulation */
当进程请求inode资源时,先检查free inode数组,看是否还有空闲项:
(1) 有:直接分配给进程。
(2) inode项已经耗尽:
先执行一个free inode数组重建过程——Loop所有的inode盘块,找到空闲的inode项,
存入free inode数组;然后再从空闲数组中分配。
基本上,上面描述的就是inode资源分配函数“ialloc”的分配算法,唯一需要多注意的
是free inode资源数组重建过程中,对空闲磁盘inode的判断方法:
(1) 7101行: i_mode为0;
(2) 7104 ~ 7106行:还需要Loop系统inode表,看该inode是否正在使用。
相应的,unix v6还提供了inode资源释放函数ifree(dev, ino)——这个函数的实现非常简单:
(1) 当free inode数组“不满”时,将要释放的inode资源放入该数组;否则,直接return;
(2) 而且,遇到文件系统“上锁”时,也直接return,不做任何处理。
——这也难怪,按照前面的描述,ialloc()本身就是“自适应”的函数,根本不需要ifree()配合。
ifree的存在只是锦上添花而已。
【性能考虑】:
上述算法中的free inode数组的全局过程会不会成为性能瓶颈?
应该不会:
(1)一个盘块可容纳256/16 = 16个磁盘inode项。而一个文件仅需要一个磁盘inode项(1/16块)——对
大多数文件来说,这远远小于文件内容所占用的磁盘块数。因此,通常情况下一个文件系统中
只需分配很小部分的盘块作inode资源。
而我们的模型所配置的RK磁盘,总共才有4800块盘块,因此,这个重建过程不会太慢;
(2) 一次重建可以恢复100个空闲资源——在当时的环境下,重建的次数也不会太频繁。
超级块中用于盘块资源管理的变量与inode管理的极其相似:
5565: int s_nfree; /* number of in core free blocks (0-100) */
5567: int s_free[100]; /* in core free blocks */
5570: char s_flock; /* lock during free list manipulation */
但是,事实上,对于盘块资源的管理,unix v6采用了完全不同的方式。
所有的空闲盘块被按照100个一组分为若干组,而每组的第一个盘块指向下一组——它记录的内容:
(1) 第一个word是下一组空闲盘块的个数;
(2) 2~…是下一组空闲盘块的块号。
因此,这些空闲盘块组就形成了一个链状结构,如下所示:
超级块中的free block资源数组记录的就是第1组盘块信息。
当分配资源时,从s_free数组里逆序进行分配,当仅剩一个entry时,就读取该盘块,获取下一组空闲盘块。
当释放资源时,如果s_free数组不满,则直接返回到该数组内;
否则,利用新释放的盘块新建一个空闲组,将s_free数组所记录的盘块号写入盘块中——即使
用“头插法”插入新组。
理解了上述过程,则资源分配和回收函数alloc()和free()就显得比较简单了。
最后我们看一下itrunc函数,它用来进行回收指定文件所占用的盘块资源,它只有一个参数,即该文
件的inode。调用该函数后,文件占用的盘块资源被回收:
(1) 文件inode的i_addr数组以及i_size0和i_size1都被置0;
(2) 如果原文件为大文件,大文件标志也被清除。
博客地址:http://blog.csdn.net/cszhao1980
博客专栏地址:http://blog.csdn.net/column/details/lions-unix.html