关于linux0.11文件系统高速缓冲的见解【《linux内核完全注释》阅读笔记】

关于linux0.11文件系统高速缓冲的见解

以下内容截选自《Linux内核完全注释(修正版v3.0)》第12章文件系统。


以上是书中完整的对高速缓冲基本概念的说明。接下来小编我挑选其中一些代码进行进一步的论述。通过以上的基本概念的阅读,我们知道minix文件系统对高速缓冲块进行了两种方式的组织,一种是一个空闲项的双向循环链表,另一种是以设备号dev和块号block为关键特征的哈希散列表。



到这里高速缓冲块管理方面的代码基本就都实现了,首先我们就看看上面这个释放缓冲块的函数brelse,细心的你一定发现为什么这里没有把缓冲块回收到空闲循环链(freelist)中去呢?很明显,这里只是把引用计数减去了1.然后,再往上一点,我们看到移出队列(remove_from_queues)和插入队列(insert_into_queues)操作都是在获取缓冲块(getblk)函数中完成的。难道不回收到freelist,显然我们对于一般意义上空闲队列freelist的理解在这里是不适用的。其实这里minix在管理高速缓冲区的时候,所谓的空闲队列中的项并不一定都是空闲的,换言之,应该说是队列中引用计数为0的项都是空闲的,另外,我们还应该注意到的是在调用getblk的时候,我们在确认到某一块可能引用计数为0的缓冲块bh以后,移出和插入操作都是在这里一次性完成的。首先我们在remove_from_queues中将bh从原来的hash散列组中移出,并从freelist队列中移出。然后我们修改了这个被孤立后的bh的设备号dev和逻辑块号block,根据新的devblock立马在insert_into_queues中将其插入到了新的hash散列组,并重新插入了freelist的尾部。这样我们也就间接保证了最新被使用的缓冲块出现在freelist的尾部,而最先被使用的缓冲块则出现在其头部。

如下为缓冲块初始化函数(buffer_init),双向循环链表freelist从这里开始实际在文件系统中就已经被分配好了完整的空间。后面的所谓释放和获取实际上是属于静态的操作,而不是动态。因为它只是去修改了一个所谓的占用标识而已。


接下来我们再看看在bitmap.c中对于申请一个逻辑块的操作函数(new_block),这里关于逻辑块位图的操作我们不讲,小编我这里还是重点说说关于高速缓冲块的操作。你会发现我们再通过getblk获取到该高速缓冲块后,只是做了一些修改标识和清除块内容的操作,便立即又调用brelse函数把他释放了。照以往对于程序的理解,这两步应该互为逆操作,同时依次调用,会被理解为什么都没有做,但是如前所述,这里针对引用计数这个变量来说,或许可以算是什么都没有做,但是在getblk的同时,别忘了,我们实际还完成了将对应这个devblock插入到缓冲块bh所对应的新的hash散列组的操作,而这部分并没有被所谓的逆操作。因此在后续我们可能调用buffer.cbread进行读取操作时,getblk通过已存在于hash表中的该高速缓冲块,便可以立刻在高速缓冲区中重新获取到该被“释放”的bh,并置其引用计数标志,以表示进程正在对其进行读操作。


 

 

 

 


  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值