分类: LINUX
2009-12-30 14:13:29
Linux文件系统设计了三类的Cache以用来支持多类型的文件系统。 一、 VFS索引节点缓存 Inode Cache VFS索引节点是一个Hash表,它不断地读取。VFS提供的索引节点缓存可以加快对文件系统的存取。每次从索引节点缓存中读取一个VFS索引节点,这样系统就可以节省读取物理设备的存取时间。 当VFS访问索引节点时,它首先查找VFS索引节点缓存。为了在VFS索引节点缓存中查找一个索引节点,系统首先计算它对应的哈希值,然后将其作为索引值 进入索引节点哈希表。然后再通过读取这个拥有相同哈希值的索引节点链表逐个匹配索引节点,直到找到具有指定设备号和inode号的索引节点。如果从缓存中 找到了索引节点,该索引节点的计数值加1。否则申请一空闲的索引节点。 二、 目录缓存 Inode Directory Cache 为了加快对常用的目录的存取,由于是根据路径访问文件的,Linux维护了表达路径与索引节点对应关系的目录缓存,被文件系统使用过的目录将会存入到该目录缓存中。这样,同一目录被再次访问时,可直接从缓冲区得到,不必重复访问存储文件系统的设备。 当真实的文件系统读取一个目录时,目录的详细信息被添加到目录缓存中。这样,同一目录被再次访问时,可直接从缓冲区找到此目录的有关信息。只有短于15个字符的目录才能保存在目录缓存中。 目录缓存由一张哈希表组成,其中每个表项指向具有同样哈希值的目录缓存链表的一个指针,哈希函数使用文件系统的设备号和目录名来计算哈希值,以便快速地找到一个目录项。为了保持一个最新的、正确的缓冲,VFS使用基于LRU(Least Recently Used)算法的目录缓冲链表。 三、 缓冲区缓存 Buffer Cache 当进程使用安装的文件系统时,它们产生很多对块设备数据块的读写请求,如下图所示。这些块读写请求会通过标准核心过程以Buffer_head数据结构的形式给出设备驱动程序需要的几乎全部信息。操作系统将设备块上的数据看作具有同样大小的数据块的线性列表。Buffer_head中的b_dev和b_blocknr属性值惟一指明了向什么设备读写第几个数据块。 (缓冲区缓存结构)见最下方的图 为了加快物理块设备的存取,Linux维护一组块缓冲区的缓存,称作Buffer Cache。它被所有物理块设备所共享。在任一时刻,由若干缓冲区为若干设备工作。数据块一经使用,就会在Buffer Cache留下备份,而且经常使用的数据将一直留在Buffer Cache中,下次再访问该数据时,如果从缓冲区缓存中可以得到有效的数据,则将节省系统去访问物理设备的时间。Buffer Cache的性能直接影响文件系统的性能。 块缓冲区高速缓存由两个功能部分组成。第一部分是空闲的块缓冲区列表。第二部分则是缓存自身。一个散列表包含了指向具有同样散列表索引的缓冲区链的指针。 散列索引是由设备标志符合数据块的块号产生的。一个块缓冲不是在空闲表中就是在缓存中。缓存中的块缓冲同时被插入到最近最少使用(LRU)列表中。对应于 每一种缓冲区类型都有一个LRU列表。 目前Linux支持以下5种缓冲区类型: Clean 未使用、新创建的缓冲区 Locked 被锁住、等待被回写 Dirty 包含最新的有效数据,但还没有被回写 Shared 共享的缓冲区 Unshared 原来被共享但现在不共享 Buffer Cache独立于任何类型的文件系统。文件系统中凡涉及到磁盘读写,几乎都通过Buffer Cache,有些甚至直接利用Buffer Cache保存信息。Linux中精心设计的Buffer Cache系统,它是由一个hash表和若干个以Buffer_Cache结构为节点的链表构成。 像所有的缓存一样,必须高效地维护缓冲区缓存,以便它有效地、公平地为块设备分配缓存表项。Linux使用bdflush监控程序执行这些Cache的看护工作。 可见,这三类的Cache分别针对索引节点、目录和块设备数据块而设计的,它们可以有效地支持Linux的文件系统。这里Linux通过对索引节点、目录和块设备数据块等各个环节而设立cache,在各个环节上都立足于提高存取的速度,这使得linux有一个高效的文件系统了。 |