引言
文件系统是操作系统最为重要的一部分,它定义了磁盘上储存文件的方法和数据结构。文件系统是操作系统组织、存取和保存信息的重要手段,每种操作系统都有自己的文件系统,如Windows所用的文件系统主要有FAT16、FAT32和NTFS,Linux所用的文件系统主要有ext2、ext3、Ext4和ReiserFS等。
我们知道,一块磁盘,要先分区,然后再格式化,否则不能使用,而这个格式化的过程,就是文件系统创建的过程,也可以这要理解,磁盘上的一个分区,就是一个文件系统。这个就像我们在使用windows系统的时候,把磁盘分区可以格式化成FAT32,也可以格式成NTFS,这个完全自己来掌握,但所格式化的文件系统必需是你使用的系统所能认出来的。这就是为什么NTFS的文件系统,不能直接被Linux系统所认识。同样,windows也不能认识EXT3/Ext4一样的道理。
关于文件系统的定义,没有一个标准的答案,如果有更高兴趣来研究文件系统的朋友,可能找相关的资料来查阅。本文只是带大家初步来了解认识文件系统。
了解一些和文件系统相关的关键词
存储介质:硬盘、光盘、软盘、Flash盘、磁带、网络存储设备等。
磁盘的分区:这是针对大容量的存储设备来说的,主要是指硬盘;对于大硬盘,我们要合理规划分区,所以要谈到硬盘的分区。
文件系统的创建:这个过程是存储设备建立文件系统的过程,一般也被称为格式化或初始化,通过一些初始化工具来进行。
挂载(mount):文件系统只有挂载才能使用,Linux的操作系统是通过mount进行的,挂载文件系统时要有挂载点,比如我们在安装Linux的过程中,有时会提示我们分区,然后建立文件系统,接着是问你的挂载点是什么。我们在Linux系统的使用过程中,也会挂载其它的硬盘分区,也要选中挂载点,挂载点通常是一个空置的目录,最好是我们自建的空置目录;
文件系统可视的几何结构:文件系统的是用来组织和排列文件存取的,所以她是可见的,在Linux中,我们可以通过ls等工具来查看其结构,在Linux系统中,我们见到的都是树形结构;比如操作系统安装在一个文件系统中,他表现为由/起始的树形结构。
Linux系统上常见文件系统格式介绍
EXT1:第一个受Linux支持的文件系统是Minix文件系统。这个文件系统有严重的性能问题,因此出现了另一个针对Linux的文件系统,即扩展文件系统。第1个扩展文件系统(ext1)由Remy Card设计,并于1992 年4 月引入到Linux中。ext1文件系统是第一个使用虚拟文件系统(VFS)交换的文件系统。虚拟文件系统交换是在0.96c 内核中实现的,支持的最大文件系统为2GB。
EXT2:第2 个扩展文件系统(ext2)也是由Remy Card 实现的,并于1993 年1 月引入到Linux中。它借鉴了当时文件系统(比如Berkeley Fast File System [FFS])的先进想法。ext2支持的最大文件系统为2TB,但是2.6 内核将该文件系统支持的最大容量提升到32TB。
EXT3:第3 个扩展文件系统(ext3)是Linux 文件系统的重大改进,尽管它在性能方面逊色于某些竞争对手。ext3文件系统引入了日志 概念,以在系统突然停止时提高文件系统的可靠性。虽然某些文件系统的性能更好(比如Silicon Graphics 的XFS和IBM® Journaled File System [JFS]),但ext3 支持从使用ext2的系统进行就地(in-place)升级。ext3 由Stephen Tweedie 实现,并于2001 年11 月引入。
Ext4:2.6.28内核是首个稳定的Ext4 文件系统。在性能、伸缩性和可靠性方面进行了大量改进。最值得一提的是,ext4 支持1EB 的文件系统。ext4 是由Theodore Tso(ext3 的维护者)领导的开发团队实现的,并引入到2.6.19内核中。目前,它在2.6.28 内核中已经很稳定(到2008 年12 月为止)。
Ext4 从竞争对手那里借鉴了许多有用的概念。例如,在JFS 中已经实现了使用区段(extent)来管理块。另一个与块管理相关的特性(延迟分配)已经在XFS 和Sun Microsystems 的ZFS 中实现。
在Ext4 文件系统中,您可以发现各种改进和创新。这些改进包括新特性(新功能)、伸缩性(打破当前文件系统的限制)和可靠性(应对故障),当然也包括性能的改善。
swap: 它是Linux中一种专门用于交换分区的swap文件系统。Linux是使用这一整个分区作为交换空间。一般这个swap格式的交换分区是主内存的2倍。在内存不够时,Linux会将部分数据写到交换分区上。
文件系统工作原理
文件系统的工作与操作系统的文件数据有关。现在的操作系统的文件数据除了文件实际内容外,通常含有非常多的属性,例如文件权限(rwx)与文件属性(所有者、用户组、时间参数等)。文件系统通常会将这两部份的数据分别存放在不同的区块,权限与属性放到inode中,数据则放到block区块中。另外,还有一个超级区块(super block)会记录整个文件系统的整体信息,包括inode与block的总量、使用量、剩余量等等等。
每个inode 与block 都有编号,至于这三个数据的意义可以简略说明如下:
superblock:记录此filesystem 的整体信息,包括inode/block的总量、使用量、剩余量, 以及文件系统的格式与相关信息等;
inode:记录文件的属性,一个文件占用一个inode,同时记录此文件的数据所在的block 号码;
block:实际记录文件的内容,若文件太大时,会占用多个block 。
由于每个inode 与block 都有编号,而每个文件都会占用一个inode ,inode 内则有文件数据放置的block 号码。因此,我们可以知道的是,如果能够找到文件的inode 的话,那么自然就会知道这个文件所放置数据的block 号码,当然也就能够读出该文件的实际数据了。这是个比较有效率的作法,因为如此一来我们的磁盘就能够在短时间内读取出全部的数据, 读写的效能比较好。
我们将inode 与block 区块用图解来说明一下,如下图所示,文件系统先格式化出inode 与block的区块,假设某一个档案的属性与权限数据是放置到inode 4 号(下图较小方格内),而这个inode 记录了档案数据的实际放置点为2, 7,13, 15 这四个block 号码,此时我们的操作系统就能够据此来排列磁盘的阅读顺序,可以一口气将四个block 内容读出来! 那么数据的读取就如同下图中的箭头所指定的模样了。
图inode/block 资料存取示意图
这种数据存取的方法我们称为索引式文件系统(indexedallocation)。下面我们来看一下windows系统中的FAT,这种格式的文件系统并没有inode 存在,所以FAT没有办法将这个文件的所有block 在一开始就读取出来。每个block 号码都记录在前一个block 当中, 他的读取方式有点像底下这样:
图FAT文件系统资料存取示意图
上图中我们假设文件的数据依序写入1->7->4->15号这四个block 号码中,但这个文件系统没有办法一口气就知道四个block 的号码,他得要一个一个的将block 读出后,才会知道下一个block 在何处。如果同一个文件数据写入的block 分散的太厉害时,则我们的磁盘读取头将无法在磁盘转一圈就读到所有的数据,因此磁盘就会多转好几圈才能完整的读取到这个文件的内容。
这就是为什么在windows系统中常常需要碎片整理, 需要碎片整理的原因就是文件写入的block 太过于离散了,此时文件读取的效能将会变的很差。这个时候可以通过碎片整理将同一个文件所属的blocks 汇整在一起,这样数据的读取会比较容易。
FAT的文件系统需要不定期进行碎片整理,那么Ext 是否需要磁盘整理呢?
由于Ext 是索引式文件系统,基本上不需要进行碎片整理。但是如果文件系统使用太久, 常常删除/编辑/新增文件时,那么还是可能会造成文件数据太过于离散的问题,此时或许会需要进行重整一下的。 不过,似乎没有多少人来进行Linux磁盘的碎片啊!
如上所说的,inode 的内容在记录文件的权限与相关属性,至于block 区块则是在记录文件的实际内容。而且文件系统一开始就将inode 与block 规划好了,除非重新格式化(或者利用resize2fs 等指令变更文件系统大小),否则inode与block 固定后就不再变动。但是如果仔细考虑一下,如果我的文档系统高达数百GB时, 那么将所有的inode 与block通通放置在一起将是很不智的决定,因为inode 与block 的数量太庞大,不容易管理。 因此Ext2文件系统在格式化的时候基本上是区分为多个区块群组(block group)的,每个区块群组都有独立的inode/block/superblock 系统。
Ext2文件系统结构详解
整体来说,Ext2格式化后有点像底下这样:
ext2文件系统示意图
在整体的规划当中,文件系统最前面有一个启动扇区(boot sector),这个启动扇区可以安装开机管理程序,这是个非常重要的设计,这样我们就能够将不同的开机管理程序安装到个别的文件系统最前端,而不用覆盖整颗硬盘唯一的MBR,这样也才能够制作出多重引导的环境啊!至于每一个区块群组(block group)的六个主要内容说明如下:
data block (资料区块)
data block 是用来放置文件内容数据地方,在Ext2 文件系统中所支持的block 大小有1K, 2K 及4K三种而已。在格式化时block 的大小就固定了,且每个block 都有编号,以方便inode 的记录啦。 不过要注意的是,由于block大小的差异,会导致该文件系统能够支持的最大磁盘容量与最大单一文件容量并不相同。 因为block 大小而产生的Ext2 文件系统限制如下图:
你需要注意的是,虽然Ext2 已经能够支持大于2GB 以上的单一文件容量,不过某些应用程序依然使用旧的限制, 也就是说,某些程序只能够捉到小于2GB 以下的文件而已,这就跟文件系统无关了!
注:
原则上,block 的大小与数量在格式化完就不能够再改变了(除非重新格式化);
每个block 内最多只能够放置一个档案的数据;
如果档案大于block 的大小,则一个档案会占用多个block 数量;
若档案小于block ,则该block 的剩余容量就不能够再被使用了(磁盘空间会浪费);
若档案很大的话,就会占用更多的block,将会降低文件系统的读写效能。
inode table (inode 表格)
再来讨论一下inode 这个吧!如前所述inode 的内容在记录档案的属性以及该档案实际数据是放置在哪几号block 内! 基本上,inode 记录的文件数据至少有底下这些:
该文件的存取模式(read/write/excute);
该文件的拥有者与群组(owner/group);
该文件的容量;
该文件建立或状态改变的时间(ctime);
最近一次的读取时间(atime);
最近修改的时间(mtime);
定义文件特性的旗标(flag),如SetUID…;
该文件真正内容的指向(pointer);
inode 的数量与大小也是在格式化时就已经固定了,除此之外inode 还有以下特色
每个inode 大小均固定为128 bytes;
每个文件都仅会占用一个inode ;
文件系统能够建立的文件数量与inode 的数量有关;
系统读取文件时需要先找到inode,并分析inode 所记录的权限与用户是否符合,若符合才能够开始实际读取block 的内容。
Superblock (超级块)
Superblock 是记录整个filesystem 相关信息的地方, 没有Superblock ,就没有这个filesystem 了。他记录的信息主要有:
block 与inode 的总量;
未使用与已使用的inode / block 数量;
block 与inode 的大小(block 为1, 2, 4K,inode 为128 bytes);
filesystem 的挂载时间、最近一次写入数据的时间、最近一次检验磁盘(fsck) 的时间等文件系统的相关信息;
一个valid bit 数值,若此文件系统已被挂载,则valid bit 为0 ,若未被挂载,则valid bit 为1 。
Superblock 是非常重要的,因为我们这个文件系统的基本信息都写在这里。一般来说,superblock 的大小为1024bytes。
Filesystem Description (文件系统描述说明)
这个区段可以描述每个block group 的开始与结束的block 号码,以及说明每个区段(superblock, bitmap, inodemap, data block) 分别介于哪一个block 号码之间。
block bitmap (区块对照表)
如果你想要新增文件时总会用到block ,那要使用哪个block 来记录呢?当然是选择空的block 来记录新文件的数据。那你怎么知道哪个block 是空的?这就得要透过block bitmap 的辅助了。从block bitmap 当中可以知道哪些block是空的,因此我们的系统就能够很快速的找到可使用的空间来处文件。 同样的,如果你删除某些文件时,那么那些档案原本占用的block号码就得要释放出来, 此时在block bitmap 当中相对应到该block 号码的标志就得要修改成为未使用的,这就是bitmap 的功能。
inode bitmap (inode 对照表)
这个其实与block bitmap 是类似的功能,只是block bitmap 记录的是使用与未使用的block 号码, 至于inode bitmap 则是记录使用与未使用的inode 号码。
最后给一张EXT3文件系统结构图,大家可以详细的来解读EXT文件系统。
注意:此图上有一点需要修正,就是MBR不在分区上,而是在磁盘的最开始位置,感谢网友ice360的提醒,请大家参阅评论部分。
摘自 羽飞博客