第十一章学习笔记

一、知识点总结:

第11章 EXT2文件系统

前言:

本章讨论EXT2文件系统。本章将引导读者实现一个完全与 Linux兼容的完整EXT2文件系

统。前提是,只要读者充分理解了一个文件系统,那么就可以轻松改编其他任何文件系统。

本章首先描述了EXT2文件系统在 Linux中的历史地位以及EXT3/EXT4文件系统的

当前状况;用编程示例展示了各种EXT2数据结构以及如何遍历EXT2文件系统树;介绍

了如何实现支持 Linux内核中所有文件操作的EXT2文件系统;展示了如何通过虚拟磁盘的

mount root来构建基本文件系统;将文件系统的实现划分为3个级别,级别1扩展了基本文

件系统,以实现文件系统树,级别2实现了文件内容的读/写操作,级别3实现了文件系统

的挂载/装载和文件保护;描述了各个级别文件系统函数的算法,并通过编程示例演示了它

们的实现过程;将所有级别融合到一个编程项目中;最后将所有编程示例和练习整合到一

个完全有效的文件系统中。

学到了什么?

1. EXt2文件系统

多年来, Linux一直使用exT2作为默认文件系统。EXT3(eXT3,2014)是EXT2的扩展。EXT3中增加的主要内容是一个日志文件,它将文件系统的变更记录在日志中。日志可在文件系统崩溃时更快地从错误中恢复。没有错误的EXT3文件系统与EXT2文件系统相同。EXT3的最新扩展是XT4。EXT4的主要变化是磁盘块的分配。

在EXT4中,块编号为48位。EXT4不是分配不连续的磁盘块,而是分配连续的磁盘块区,称为区段。除了这些细的更改之外,文件系统结构和文件操作保持不变。本书的目的是讲授文件系统的原理。主要目标并非实现大的文件存储容量,而是重点论述文件系统设计和实现的原则,强调简单性以及与 Linux I的兼容性。

2. 在 Linux下,命令

   mke2fs [-b blksize -N inodes] device blocks

在设备上创建一个带有 blocks个块和 inodes个索引节点的EXT2文件系统。设备可以是真实设备,也可以是虚拟磁盘文件。如果未指定 E blksize,则默认块大小为1KB。如果未指定 ninnies,mke2s将根据 blocks计算一个默认的 I inodes数。得到的EXT2文件系统可在 Linux中使用。

3.块组描述符

Bock#2:块组描述符块eXT2将磁盘块分成几个组。

每个组有8192个块(硬盘上的大小为32K)每组用一个块组描述符结构体来描述由于一个虚拟软盘(FD)只有1440个块,B2就只包含一个块组描述符。其余的都是0在有大量块组的硬盘上,块组描述符可以跨越多个块。

块组描述符中最重要的字段是bgblock bitmap、 bg inode bitmap和 bg inode table,它们分别指向块组的块位图、索引节点位图和索引节点起始块。

4.索引节点
每个文件都用一个128字节(EXT4中是256字节)的唯一索引节点结构体表示。下面列出了主要索引节点字段。block[15]数组包含指向文件磁盘块的指针,这些磁盘块有

  • 直接块: i block[0]至 i block[,指向直接磁盘块。

  • 间接块: i block[12]指向一个包含256个块编号(于1 KB BLKSIZE)的磁盘块,每个块编号指向一个磁盘块。

  • 双重间接块: i block[13指向一个指向256个块的块,每个块指向256个磁盘块。

  • 三重间接块: i block[11是三重间接块。对于“小型”EXT2文件系统,可以忽略它。

5.索引节点

索引节点大小(128或256)用于平均分割块大小(1B或4KB),所以,每个索引节点块都包含整数个索引节点。在简单的EXT2文件系统中,索引节点的数量是184个(inux默认值)。索引节点块数等于184/8-23个。

因此,索引节点块为B10至B32。每个索引节点都有一个唯一的索引节点编号,即索引节点在索引节点块上的位置+1。注意,索引节点位置从0开始计数,而索引节点编号从1开始计数。0索引节点编号表示没有索引节点根目录的索引节点编号为2。同样,磁盘块编号也从1开始计数,因为文件系统从未使用块0。块编号0表示没有磁盘块。

6.遍历算法

  • (1)读取超级块。检查幻数 s magic(0xEF53),验证它确实是EXT2FS。

  • (2)读取块组描述符块(1+ s first data block),以访问组0描述符。从块组描述符的bg inode table条目中找到索引节点的起始块编号,并将其称为 InodesBegin Block

  • (3)读取 Inode Begin Block,获取/的索引节点,即 INODE#2。

  • (4)将路径名标记为组件字符串,假设组件数量为n。例如,如果路径名=/ab/c,则组件字符串是“a”“b"“c”,其中n=3。用nme[0],name1],…,name[n-1]来表示组件。

  • (5)从(3)中的根索引节点开始,在其数据块中搜索name[0]为简单起见,我们可以假设某个目录中的条目数量很少,因此一个目录索引节点只有12个直接数据块。有了这个假设,就可以在12个(非零)直接块中搜索nme[0].

7.文件系统的结构

当前运行进程的PROC结构体。在实际系统中,每个文件操作都是由当前执行的进程决定的每个进程都有一个cwd,指向进程当前工作目录(CWD)的内存索引节点它还有一个文件描述符数组fd,指向打开的文件实例。

  • 文件系统的根指针。它指向内存中的根索引节点。当系统启动时,选择其中一个设备作为根设备,它必须是有效的EXT2文件系统根设备的根索引节点( inode#2)作为文件系统的根加载到内存中该操作称为“挂载根文件系统”

  • 一个 open Table条目。当某个进程打开文件时,进程fd数组的某个条目会指向openTable, open Table指向打开文件的内存索引节点内存索引节点。当需要某个文件时,会把它的索引节点加载到 minde槽中以供使用。因为索引节点是唯一的,所以在任何时候每个索引节点在内存中都只能有一个副本。在 minde中,(dev,ino)会确定索引节点的来源,以便将修改后的索引节点写回磁盘refCount字段会记录使用 inode的进程数。

  • drty字段表示索引节点是否已被修改。挂载标志表示索引节点是否已被挂载,如果已被挂载, mntabPtr将指向挂载文件系统的挂载表条目lck字段用于确保内存索引节点一次只能由一个进程访问。

  • 是已挂载的文件系统表。对于每个挂载的文件系统,挂载表中的条目用于记录挂载的文件系统信息,例如挂载的文件系统设备号。在挂载点的内存索引节点中,挂载标志打开, mniabPtr指向挂载表条目。在挂载表条目中, mntPointPtr指向挂载点的内存索引节点后面将会讲到,这些双链接指针允许我们在遍历文件系统树时跨越挂载点。

  • 此外,挂载表条目还可能包含挂载文件系统的其他信息,例如超级块、块组描述符、位图和索引节点启动块的值,以便快速访问。如果任何缓存项有修改,当卸载设备时,必须将它们写回设备。

8.索引节点的一般使用方式是

  • 更改目录( chdir):iget新目录的 minde,但是iput旧目录的 I minde

  • 打开(open):iget文件的 inode,当文件关闭时释放

  • 挂载( mount)):iget挂载点的 minde,稍后通过卸载释放。

9.mkdir算法

mkdir命令

 mkdir pathname

创建了一个带路径名的新目录。将新目录的权限位设置为默认值0755(所有人可以访问和读写,其他人可以访问但只能读取)。

mkdir算法的大多数步骤都无须解释。要创建一个目录,我们需要从索引节点位图中分配一个索引节点,并从块位图中分配一个磁盘块,分配操作依赖于测试。为了保持文件系统的一致性,分配一个索引节点后,必须将超级块和组块描述符中的空闲索引节点计数减1。同样,分配一个磁盘块后,也必须将超级块和块组描述符中的空闲块数减1。

10.文件锁定

文件锁定机制允许进程对一个文件或文件的某些部分设置文件锁,以防止在更新文件时出现竞态条件。文件锁可共享(允许同步读取),也可独占(执行独占写)。文件锁既可以是强制性的,也可以是建议性的。例如, Linux既支持共享文件锁,也支持独占文件锁,但文件锁定只是建议性的。在 Linux I中,文件锁可通过ntl(系统调用设置,也可通过fock系统调用操作。为简单起见,我们假设一种非常简单的文件锁定。

当一个进程试图打开一个文件时,将会检查目标操作模式的兼容性。唯一容模式是读模式。如果已经为更新模式打开了一个文件,即写读写追加,则该文件无法再次打开。但是,这并不会阻止相关进程(例如父进程和子进程)修改父进程打开的同一文件,而且在Unix/ Linux中同样如此。在这种情况下,文件系统只能保证每个写操作是原操作,但不能保证进程的写入顺序,写入顺序取决于进程调度。

11.文件系统项目的扩展

简单的EXT2文件系统使用1KB块大小,只有一个磁盘块组它可以轻松进行以下扩展。

(1)多个组:组描述符的大小为32字节对于1KB大小的块,一个块可能包含

1024/32=32组描述符。32个组的文件系统大小可以扩展为32*8=256MB

(2)4KB大小的块:对于4KB大小的块和一个组,文件系统大小应为4*8=32MB。

对于一个组描述符块,文件系统可能有128个组,可将文件系统大小扩展到128*32=4GB

对于2个组描述符块,文件系统大小为8GB等。大多数扩展都很简单,适合用于编程项目。

(3)管道文件:管道可实现为普通文件,这些文件遵循管道的读/写协议。此方案的优点是:它统一了管道和文件索引节点,并允许可被不相关进程使用的命名管道。为支持快速读/写操作,管道内容应在内存中,比如在 RAMdisk中。必要时,读者可将命名管道实现为FIFO文件。

(4)I/O缓冲:在编程项目中,每个磁盘块都是接读写的。这会产生过多的物理磁盘I/O操作。为提高效率,实际文件系统通常使用一系列I缓冲区作为磁盘块的缓存内存。文件系统的IO缓冲将会在第12章中讨论,但是可把它合并到文件系统.

原文地址:https://www.cnblogs.com/Werido-/p/15417070.html