索引节点的提出
对于存储在磁盘空间上的文件,实现快速的读写和索引是影响用户使用体验的关键。和PCB类似的文件控制模块FCB提供了足够的文件属性,在搜索匹配过程中,显然文件名匹配是搜索过程的关键,并且是唯一标识符,可FCB拖家带口,比较时显然过于臃肿,其他信息暂时都用不上。操作系统一般又是将FCB组成的文件目录放在磁盘上,对较为庞大的文件系统,显然需要多次进行磁盘IO读写。
举例:假设一个FCB数据结构大小为128B,盘块大小1KB,则一个盘块只能放下8个FCB,假设现在有个文件系统含有640个文件,即640个FCB元素,假设磁盘缓存也是1KB,假设系统搜索文件采用顺序检索法(路径名依次匹配)则在该文件目录下用遍历的方式搜索一个文件,平均需要启动磁盘IO读写40次。
考虑上述情况,显然可以想到只需要将文件名和文件具体描述信息(大小,owner,权限等)分离,即把文件具体描述信息单独收编起来,该数据容器便被称为”索引节点“,Linux系统中的文件目录项只由文件名和指向索引节点的指针组成,从而形成高效精简的搜索目录。
接着上面的例子,现在精简后,一个文件目录项只需要16B(14B用于文件名,2B用于索引节点指针),则现在一个盘块可以放下64个文件的目录信息,针对同样的640个文件,文件目录占用10个盘块,则现在平均搜索一个文件只需要启动磁盘读写5次,速度提升显而易见。
梳理下用户访问文件时操作系统发生的操作顺序:1.操作系统内核根据文件名查找文件目录,找到它的FCB或这索引节点号;2.经过合法性检查,从索引节点中找到该文件所在的物理地址(文件逻辑块和物理盘块的映射关系保存在索引表中);3.启动磁盘驱动程序,将所需的文件读入内存。
Linux混合多重索引结构
说完这些文件管理系统背后的共性基础,现在来看Linux采用的文件管理系统EXT( extended file system EXT2/EXT3依旧是主流,EXT4拥有诸多新的特性EXT3可以经过简单操作便可在线升级到EXT4)。从物理结构上,Linux采用混合多重索引结构,将将文件所占用盘块block的盘块号直接或间接地存放在该文件索引节点Iinode的地址项中,在Linux中索引节点被称为inode,大小128B,记录一个block要花费4B(32位系统),在EXT2/3系统规定inode中含有12个直接地址项,1个一次间接项(指向一重索引表),1个二次间接项(指向二重索引表),1个三次间接项(指向三重索引表)。
对于EXT2,inode和block一开始就规划好了(数量和大小),除非重新格式化否则不再变动。inode大小始终不变为128 B,盘块单位有1KB,2KB,4KB三种选择,假设盘块最小单位规定为1KB,那么可计算得到EXT2支持的最大单文件容量size=(12+256+256^2+256^3)*1 KB=16 GB.
EXT2/3这种混合多重索引结构是种经典的平衡策略(取长补短,取直接块索引的快速,取间接索引的大容量),原因如下:
1. 直接寻址:因为Linux系统中以中小型文件流为主,几十KB很常见,这时采用直接寻址即采用inode中的12个直接地址项,可以有效减低IO次数,这也是这些块被称为直接块的原因;
2. 一次间接寻址:当文件达到几百KB时,Linux提供一次间接寻址,顶层索引节点中存放的是直接块的块号对应表;
3. 多次间接寻址方式,依次类推。
从上面分析可以看到,混合索引结构对于小文件保证快速访问,对于大文件也能提供较好的支持。
文件逻辑块和磁盘存储物理块的转换过程:
- Linux系统中,被打开的文件都有一个读写指针,用以指示当前读取的位置。偏移量是从文件第一个字符开始计算。计算方式:字节偏移量除以盘块block大小,其商为逻辑块号,余数为块内位移量;
- 将文件逻辑块号转换为物理块号,Linux系统中直接地址项为12个,当文件逻辑块号小于12,将逻辑块号转换为物理块号的方法是将文件的逻辑块号转换为索引节点的地址项下标,便可获取文件相应的物理盘块号。但文件逻辑块号大于12小于268,则采用一次间接地址方式,依次类推。
VFS虚拟文件系统
EXT2/3文件系统只是当下主流的诸多文件管理之一,不同场景下处于不同的使用目的存在着不同性能侧重的文件管理系统,EXT体系是Linux常用的文件系统,FAT体系和NTFS则是Windows支持的,XFS文件系统则由SGI公司通过保持cache的一致性、定位数据和分布处理磁盘请求来提供文件系统数据的低延迟、高带宽访问;ReiserFS在上百G的企业级文件管理系统提供较好的性能保证。
Linux为支持这些不同的文件系统,进行了一层抽象封装,提供了VFS(虚拟文件系统virtual filesystem switch),统一提供标准的文件管理接口API,从而实现对不同文件系统的开放性支持。