Appearance
5.5 Linux文件系统
一、Linux文件系统
1. 概述
Linux是一个unix类操作系统。
Linux中用EXT2文件系统结构。
在EXT2文件系统中,查找文件的过程:
- 当访问一个文件时,通过文件名在“目录表”中查到其“索引节点号”。
- 通过“索引节点号”查“索引节点表”。
- 通过“索引节点表”得到其“索引节点”。
- 通过索引节点得到文件数据所在位置。
2. 目录及文件分配表的实现
EXT2文件系统的物理结构
整个盘卷由多个数据块组构成。一个数据块代表一个文件系统。
EXT2的物理结构中各字段的含义:
超级块:存储着描述文件系统大小和形状的基本信息。
组描述符:描述它的数据结构。(块位图大小、索引节点位图大小、索引节点表大小、空闲块数、空闲索引节点数、已用目录数等重要信息)。
块位图:描述了该块组中数据块空间的使用情况,在数据块分配和数据块撤销时使用。
索引节点位图:描述了该块组索引节点表所占空间的信息,在索引节点的分配和撤销中使用。
索引节点表:记录了本块组中索引节点集合。
数据块:用于存放文件数据。
EXT2的目录
一个文件对应有一个目录项。
目录项包含该文件对应的索引节点号、文件名、名字长度等信息。
目录是一些特殊的文件,称为目录文件,其中包含了该目录下所有文件的目录项集合。
目录文件结构示例图 :
EXT2的索引节点
EXT2的索引节点中的信息含义:
Mode:用户拥有的权限。(R、W、E) 。
Owner Information:文件或目录所有者的用户和组标识符。
Size:文件大小。
Timestamps:索引节点建立的时间和索引节点最后修改的时间。
Data blocks:描述文件的数据块。
文件控制块的实现
当打开一个EXT2文件时,把要打开文件的管理控制信息从辅存的目录项和索引节点中读到内存,形成FCB,并将该FCB的地址以一个文件描述符(FD)的形式返回给用户进程。
根据FD可获得文件的描述信息。
通过这些信息用户可对实际物理文件进行操作。
二、LINUX VFS的缓存管理
LINUX的虚拟文件系统(VFS)——将实际的文件系统的数据结构转换成统一的内存VFS的数据结构来兼容多种文件系统类型。
VFS的缓存实现分为三个具体的缓存类型:
- 数据缓存
- 索引节点缓存
- 目录缓存
1. 数据缓存
任何一个从块设备中读取的数据块或者往块设备中写入的数据块都要通过缓存。
缓存中的数据块是以拥有此数据块的设备的设备标识符和缓冲区的块号来唯一标识的 。
缓存由两部分组成:
第一部分是空闲的缓冲区链表。
第二部分是非空闲的缓冲区。由指针数组构成的散列表,散列表中hash值由设备的标识符和数据块的块号产生的,表中的指针指向具有相同hash值的缓冲区。
数据缓存结构:
Linux系统现在支持以下几种类型:
干净的(clean):未被使用的,新的缓冲区。
锁定的(locked):已经被锁定的缓冲区,等待数据的写入。
已用的(dirty):也就是缓冲区中包括已改变的新数据,这些数据将要被写入到磁盘中。
共享的(shared):可以共享的缓冲区。
非共享的(unshared):现在不能被共享的缓冲区。
缓存管理的bdflush守护进程
linux系统使用bdflush内核守护进程来完成缓存管理。
内核守护进程bdflush——在系统启动时作为一个系统的线程运行,在大部分时间中,此守护进程都处于睡眠状态,等待系统中被改动的数据块缓冲区的数量增大到一定的值,bdflush守护进程将被唤醒。
内核守护进程bdflush的任务是当缓存中被改动的缓冲区数量太多时,提供一个管理功能。
2. 索引节点缓存
VFS提供的索引节点缓存可以加快对系统中文件的存取。
VFS索引节点缓存使用散列表实现,表项的hash值是通过索引节点号和存储文件系统的物理设备号计算出来的,各表项指向具有相同hash值的VFS索引节点链表的指针。
VFS索引节点缓存的操作
如果系统在索引节点缓存中找到索引节点,那么此索引节点的计数器将加1,表明又有一个进程在使用该索引节点。否则,系统必须申请一个空闲的VFS索引节点,系统读取该索引节点到内存缓存。
如果系统已经没有可分配的空闲索引节点时,那么必须查找一个已用的索引节点,将那些用户计数器为0的索引节点重新分配(说明系统中没有任何进程正在使用这些索引节点)。
一些非常重要的索引节点,如文件系统的根目录索引节点,它们的索引节点计数器总是大于0,以保证永远不能被重新分配。
不论用什么方法找到一个新的索引节点,系统都必须调用一个特殊的子程序来把实际文件的信息添加到此索引节点中。
当向新的索引节点中写入信息时,锁定此索引节点,将索引节点计数器置为1,直到索引节点中的信息写完后,再解锁。
如果它被锁定时,则其他需要访问该索引节点必须等到解锁后才能进行。
3. 目录缓存
为了加速对常用目录的存取,VFS维护一个两层LRU目录缓存链表。
目录缓存包括一个散列表,表的hash值由设备号和目录名来计算,每个表项指向具有相同hash值的目录缓存链表的指针。
当读取一个目录时,目录的详细信息将添加到目录缓存中。