从API到SD卡驱动---探密Linux文件系统(2)

来源:互联网 发布:mysql注入点测试 编辑:程序博客网 时间:2024/05/29 05:03

第二节           Ext2文件系统

一、简介

ext2Linux自行设计且具有较高效率的一种文件系统,虽然最新的Linux版本已经将ext3作为默

认的文件系统,但是作为一种经典的文件系统,ext2在性能和健壮性上依然具有其独特的优点,它建立在超级块、块组、i结点、目录项等概念的基础上,ext2文件系统灵活、功能强大而且在性能上进行了全面优化,并且在内存映射、数据块申请与释放也有自己独到之处

 

二、ext2特性

1.支持标准的UNIX特性:

(1) 支持UNIX文件类型,如普通文件,目录文件,特殊设备文件。(/include/linux/stat.h, L12-25

(2) 支持4GB文件和长文件名,字符达255个字符,且文件名在目录项中是变长,所以不浪费空间。

(3) ext2为超级用户保留了一些块,一般会有5%的数据块预留。这样允许超级用户在用户进程占满文件系统时重新恢复。

 

2Ext2特有性能:

(1) 具有同步更新的能力。文件系统安装时默认设置超级用户需要修改inode,位图块,间接块、目录块等数据同步写到磁盘。

(2) ext2文件系统允许超级用户在创建文件系统时选择逻辑块大小。

(3) ext2文件系统对数据块的分配采用了优化策略。Ext2尽量从同一块中分配数据块作为文件的索引结点,从而使索引结点与数据块在磁盘上靠得很近,在访问文件时减少了磁头的移动,减少了访问次数; 在给文件分配数据块或写文件的时候,它总是预分配多达8块的连续数据块,方便文件动态增加,同时也方便数据块位图, 同时也使得文件的读写I/O速度大大提高。

 

3ext2文件系统的逻辑结构与物理结构

(1) ext2文件系统的物理i结点与内存i结点的数据结构

文件一被打开后,其物理i结点的内容会由系统复制到内存i结点。内存i结点中,除了从物理i结点复制来的文件静态信息外,还有针对该文件在使用过程中产生的活动信息。

物理i结点 ext2_inode               (/include/linux/ext2_fs.h)

内存i结点 ext2_inode_info                (/include/linux/ext2.h)

(2) ext2文件的物理结构

Ext2索引结点中,数据块指针数组共有15项,前12个为直接块指针,后三个分别为“一次间接块指针”、“二次间接块指针”、“三次间接块指针”

这种文件的物理组织方式基本沿用了UNIX的方法,其优点在于兼顾了大中小文件的物理组织。对于中小文件致力于其读写速度快,而对于大文件或巨型文件则满足其能够使用的要求。

按每块大小1KB计算,指针长度32位占4B,则每个索引块能放索引指针是256个,照此计算每级索引可容纳的文件物理块数最多为:

直接索引:12                               12KB

一级索引:256                             256KB

二级索引:256^2=65536               64MB

三级索引:256^3=16777216     16384MB=16GB

所以理论上文件可容许的对大长度是12K B+256KB+64MB+16GB, 而实际可容纳的文件最大长度在文件 i结点中决定。由于文件长度字段是32位,所以系统可接受的文件最大长度为4GB

若块变化,  块长 1024  容量为16.06GB

                  2048         256GB

                  4096         4TB

 

 

 

 

 

4ext2文件系统对存储空间的管理

(1) ext2文件系统磁盘格式

 

 

 

 

 

 

 

超级块的内容可以用”tune2fs -l””dumpde2fs”等来显示。 下面是用tune2fs查到的某磁盘超级块内容:

 

首先,从上面可知道,该设备可用的记录块数量是1540097(也就是大约1.5G字节,在格式化时,可能会浪费少量记录块) 而每个组的大小是8192块,所以共有1540097/8192=188组,每个组描述符表占用6(188/32=6)。但是,8192*188=1540096块,其实这多出的一块就是引导块。

其次,每个组含有2056个节点,所以共有2056*188=386528个索引节点;而每个块能放置8个索引点信息(块大小为1K,索引节点大小为128字节,1024/128=8)。这样,每个组中需要耗费2056/8=257块来用于记录索引节点。

再有,目前设备上还有221060个空闲块,但是其中77011个是保留的,保留占总容量5%, 是用于当某些记录块摔损坏时来作为替换用。

再通过”df”,命令,查下。结果表明该设备共有14900881K的块,其中已用1269028个块,还有144049空闲块。这些数据怎么跟上面联系呢?  这里,1490088就是设备上真正用于数据块的块数量,也就是每组有1490088/188=7926个块

结论:

1(超级块)+6(组描述符表)+1(块位图)+1(索引节点位图)+257(索引节点表)+7926(数据块) = 8192

 

(2) ext2的主要数据结构

物理超级块ext2_super_block 调入内存后形成内存超级块ext2_sb_info的一部分。内存超级块是系统对磁盘空间进行管理的依据。

组描述符是系统对块组进行管理的数据结构,每个块组(ext2_group_desc)一个,它描述一个块组的信息,磁盘上所有组的描述符放在一起,构成组描述符表,记录了磁盘上所有组的信息。

在每个块组中使用了两个块,分别用来记录各个数据块的使用情况和索引节点表的使用情况,即块位图和索引节点位图。每一位代表一个数据块或一个索引节点,为1表示占用,为0表示空闲。每个位图必须在一个单独的块内。例如:4K大小的块,可以描述32768个数据块的状态。

Ext2目录文件的结构ext2_dir_entry_2

 

 

 

(3) ext2系统中找一个文件

Linux 的文件名和所有的 Unix 文件名的格式一样。它是一系列目录名,用“ / ”分隔,以文件名结尾。如:/home/rusling/.cshrc ,其中 /home /rusling 是目录名,文件名是.cshrc

为了在EXT2 文件系统中找到代表这个文件的 inode ,系统必须逐个解析目录中的文件名直到得到这个文件。

首先需要找到文件系统的第一个inode---inode。通过超级块可找到它的编号。假如根的inode编号是42,则找到块组0中的 inode 表中的第42inode。从根inode的模式描述可知它是一个EXT2目录,它的数据块包括EXT2目录条目。Home是这些目录条目之一,这个目录条目可提供描述/home目录的 inode编号。读取这个目录(首先读取它的 inode ,然后读取从这个 inode描述的数据块读取目录条目),查找rusling条目,给出描述 /home/rusling目录的inode编号。最后,读取描述/home/rusling目录的inode指向的目录条目,找到.cshrc 文件的 inode 编号,从而得到包括文件信息的数据块

 

 

Ext3简介

EXT3,是在EXT2基础上设计的,可以说是EXT2 + Journal(日志)。Journal 是为提高可靠性而设计的一个特殊的文件(确切说来也可以不是文件)。基本过程是,把对文件系统操作划分为一个个事务,使用Journal记录这些事务,然后再实际执行他们。这样,即使由于当机,导致事务没有完成,也可以根据日志,快速的把文件系统恢复到一个正确的状态。

1、文件系统特点

文件系统保存两类数据:元数据(meta-data)和用户数据。元数据即分区特征、目录结构、文件属性等, 即有六种元数据:超级块、块组描述符、索引节点、用于间接寻址的块(间接块)、数据位图块和索引节点块。

      

比如ext2分区中建立一个文件,需要完成这几步:

a.      分配inode  

b.需要找到他所在目录的inode,向他的数据中加入新的目录项,  

c.分配文件所需的数据块。  

d.修改分配inode的数据  

 

显然这里至少修改了:  

  1superblock+1inode-bitmap   +   1inode-table+   1block-bitmap  

  这四个块。这也意味着,有了这四个块的正确数据,就足够把这个操作恢复了。

 

2Journal记录的数据

Ext3 让系统管理员决定应当把什么记入日志;具体来说,它提供三种不同的日志模式:

       1)日志(Journal

文件系统所有数据和元数据的改变都记入日志。这种模式减少了丢失每个文件所作修改的机会,但是它需要很多额外的磁盘访问。例如,当一个新文件被创建时,它的所有数据块都必须复制一份作为日志记录。这是最安全和最慢的Ext3日志模式。

无论数据和元数据,都写入日志中。

 

(2) 预定(Ordered

只有对文件系统元数据的改变才记入日志。然而,Ext3文件系统把元数据和相关的数据块进行分组,以便把元数据写入磁盘之前写入数据块。这样,就可以减少文件内数据损坏的机会;例如,确保增大文件的任何写访问都完全受日志的保护。这是缺省的Ext3 日志模式。

在数据写入日志后,就将元数据写入日志。

 

(1)    写回(Writeback

只有对文件系统元数据的改变才记入日志;这是在其他日志文件系统发现的方法,也是最快的模式。

数据和元数据经过一定周期定时日志区域,然后在系统空闲时再写入真正的文件系统。

 

3、日志块设备层(JBD, Journal Block Device)

Ext3 日志通常存放在名为.journal 的隐藏文件中,位于文件系统的根目录。

Ext3 文件系统本身不处理日志,而是利用所谓日志块设备(JournalingBlock Device)或叫JBD 的通用内核层。

JDB层是相当复杂的软件部分。Ext3文件系统调用JDB例程以确保在系统万一出现故障时它的后续操作不会损坏磁盘数据结构。然而,JDB通常使用同一磁盘来把Ext3文件系统所做的改变记入日志,因此,它与Ext3 一样易受系统故障的攻击。换言之,JDB 也必须保护自己免受可能引起日志损坏的任何系统故障。

因此,Ext3 JDB 之间的交互本质上基于三个基本单元:

(1)日志记录

描述日志文件系统一个磁盘块的一次更新。

(2)原子操作

包括文件系统的一次高级修改对应的日志记录;具体来说,修改文件系统的每个系统调用都引起一次单独的原子操作处理。

(3)事务

包括几个原子操作,原子操作的日志记录对e2fsck 同时也标记为有效。

 

4、例子

   1)日志内容

例如我要创建一个新文件,自然要分配新的索引节点和数据块,也就是要修改索引节点位图和块位图。那么日志记录的是旧的块还是新的块,即记录修改前的位图还是修改后的位图?似乎是修改后的位图,即新块。

每次系统调用所执行的操作称为一个原子操作,多个原子操作可以合并到一个事务中,但一个事务能够接收的原子操作是有限的,例如更新1024个不同的块等。事务(称为runningtransaction)无法接收新的原子操作后,就会被强制提交(committing transaction),然后开始一个新的事务.

例如先写文件1,后在写文件2,它们的所有的修改位图、修改索引节点、修改组描述符、修改超级块、写数据操作(如果是journal模式)都可以合并到一个事务中,看成一个完整的操作。

日志记录的是由一个个完整的事务记录组成,每个事务记录结构为【1描述符块+若干元数据块】×N+1提交块。描述符块描述后面的的若干元数据块的原始信息,一个元数据块对应一个描述结构,描述结构给出该元数据块原始块号信息。xN的意思是一个描述符块最多只能存放一定量的描述符,元数据太多的话需要更多的描述符块。最后加上一个提交块,表明事务已经被完整地记录下来了,如果此时宕机的话就可以凭此还原元信息了.

事务记录的是本次事务中被修改过的元数据信息。

 

(2)日志回写

事务被写入日志后,原始信息怎么办呢,是不是立即更新到磁盘?

jbd的做法是无限期延迟,直到

a..相关的buffer_head被内存管理子系统或bdflush写入磁盘

b..日志记录已满,无法开始新的事务,系统强制回收checkpoint事务,flush所有的相关buffer_head到磁盘,释放check point事务.

 Jbd中有一个专门的线程(执行的函数   fs/jbd/journal.c:   int   kjournald(void*))来根据一定的时间间隔去写将事务写入journal文件。

 

   (3)Journal中包含的事物

一个journal可以有三种状态的事务:

(i).一个正在运行的事务,它可以接收新的原子操作
(ii)
一个正在提交的事务,不能接收新的原子操作,准备将事务写入日志
(iii)
若干个已提交日志(即已写入日志),它们不能被立即释放,因为真实的写操作并未完成,因此事务处于check point状态,即由kjournald定时检查与该事务相关的buffer head是否已经被全部写入磁盘,如果是就释放该事务,相应的盘上事务记录被销毁,从而回收了日志空间.

       (4)当一个事务超时,就会被强制提交。但没有被立即执行回写,而是被推迟了。

                                                      

 

 

如果没有JBDExt3的流程是红线;如果有则是绿线。下面对图的1-5阶段做介绍。

 

1 在数据准备提交的时候,先由JBD2根据系统设置的不同(writeback, ordered, journal)把对数据的操作写入备份,如果在这之前或是还没写完的时候系统发生了故障(如断电),那么在系统下次完整性检查时就把这些日志数据删除,而不对文件系统做任何改变。

 

2 如果到这一步,说明备份数据已经写完,在以后的任何一步发生故障,系统都能根据日志把完整的备份数据写到相应的文件系统里去。当然这些完整情只能保证一个原子操作不完整性。假如你在拷贝一个600M的电影,一个原子操作是10M,那么JBD2系统只能保证下在提交的10M的数据的完成性,页不能保证这个电影的完整性。

 

 

3如果到这一步发生故障,那么数据还没有写入设备,或是没有完全写入设备,那么下次进行完整性检查时就会把数据补全,然后执行4-5这个两个。45也一样的,不过起点不一样,终点都一样的,所谓的殊途同归。

 

 

 

5、日志的建立流程:

ext3_fill_super() ==>  ext3_load_journal() ==>ext3_get_dev_journal() ==>journal_init_dev()

6、日志系统是怎么把数据记录到日志分区或是目录里?

 

 


原创粉丝点击