文章目录

  • ​​一、文件系统需要解决的问题​​
  • ​​二、ext2文件系统​​
  • ​​1.总体存储布局​​
  • ​​2.实例剖析​​
  • ​​(1)dd if=/dev/zero of=fs count=256 bs=4K​​
  • ​​(2)mkf2fs fs​​
  • ​​(3)dump2fs fs​​
  • ​​(4)mount -o loop fs /mnt 和lost+found的含义​​
  • ​​(5)od -tx1 -Ax fs​​
  • ​​(6)dubugfs fs​​
  • ​​3.数据块寻址​​

一、文件系统需要解决的问题

(1)文件系统在内核中是如何实现的?如何呈现给用户一个树状的目录结构?如何处理用户的文件和目录操作请求?

(2)磁盘是一种顺序的存储介质,一个树状的目录结构如何扯成一条线存到磁盘上?

(3)怎样设计文件系统的存储格式使访问磁盘的效率最高?各种文件和目录操作在磁盘上的实际效果是什么?

(4)文件系统的表示和存储

(第29章)LInuxC系统编程中的文件系统_文件系统

二、ext2文件系统

1.总体存储布局

  • 下图是一个磁盘分区格式化成ext2文件系统后的存储布局。

    (1)一个磁盘可以划分成多个分区,每个分区必须先用格式化工具(例如某种 mkfs 命令) 格式化成某种格式的文件系统,然后才能存储文件,格式化的过程会在磁盘上写一些管理存储布局的信息

(2)文件系统中存储的最小单位是块(Block)
一个块究竟多大是在格式化时确定的,例如 mke2fs 的 -b 选项可以设定块大小为1024、2048或4096字节

(3)图中启动块(BootBlock) 的大小是确定的,就是1KB
启动块是由PC标准规定的,用来存储磁盘分区信息和启动信息,任何文件系统都不能使用启动块

(4)启动块之后才是ext2文件系统的开始,ext2文件系统将整个分区划成若干个同样大小的块组(Block Group) ,每个块组都由以下部分组成:

(第29章)LInuxC系统编程中的文件系统_根目录_02


(第29章)LInuxC系统编程中的文件系统_数据块_03


(第29章)LInuxC系统编程中的文件系统_数据块_04


(5)为什么用 df 命令统计整个磁盘的已用空间非常快呢?

因为只需要查看每个块组的块位图即可,而不需要搜遍整个分区。相反,用 du 命令查看一个较大目录的已用空间就非常慢,因为不可避免地要搜遍整个目录的所有文件。(6)与此相联系的另一个问题是:在格式化一个分区时究竟会划出多少个块组呢?

(第29章)LInuxC系统编程中的文件系统_数据块_05


(7)

eg1:在 home 目录下 ls -l :

(第29章)LInuxC系统编程中的文件系统_数据块_06


eg2:

(第29章)LInuxC系统编程中的文件系统_文件系统_07


eg3:符号链接和硬链接

(第29章)LInuxC系统编程中的文件系统_文件系统_08


eg4:再研究一下目录的硬链接数

(第29章)LInuxC系统编程中的文件系统_数据块_09

2.实例剖析

(1)dd if=/dev/zero of=fs count=256 bs=4K

如果要格式化一个分区来研究文件系统格式则必须有一个空闲的磁盘分区,为了方便实验,我们把一个文件当作分区来格式化,

首先创建一个1MB的文件并清零:

(第29章)LInuxC系统编程中的文件系统_根目录_10

(2)mkf2fs fs

做好之后对文件 fs 进行格式化,也就是把这个文件的数据块合起来看成一个1MB的磁盘分区,在这个分区上再划分出块组

(第29章)LInuxC系统编程中的文件系统_数据块_11

(3)dump2fs fs

用 dumpe2fs 工具可以查看这个分区的超级块和块组描述符表中的信息:

(第29章)LInuxC系统编程中的文件系统_数据块_12


(第29章)LInuxC系统编程中的文件系统_数据块_13

(4)mount -o loop fs /mnt 和lost+found的含义

  • 用常规文件制作而成的文件系统也可以像磁盘分区一样 mount 到某个目录

(5)od -tx1 -Ax fs

现在我们用二进制查看工具od查看这个文件系统的所有字节,并且同 dumpe2fs 工具的输出信息相比较,就可以很好地理解文件系统的存储布局了

(第29章)LInuxC系统编程中的文件系统_文件系统_14

  • 超级块信息
  • 块组描述符信息

(6)dubugfs fs

  • 探索文件系统还有一个很有用的工具 debugfs ,它提供一个命令行界面,可以对文件系统做各种操作,例如查看信息、恢复数据、修正文件系统中的错误
  • 下面用 debugfs 打开 fs 文件,然后在提示符下输入 help 看看它都能做哪些事情:
  • 在 debugfs 的提示符下输入 stat / 命令, 这时在新的一屏中显示根目录的inode信息:
  • 把以上信息和 od 命令的输出对照起来分析:

    解释如下:
  • 上图中的 st_mode 以八进制表示, 包含了文件类型和文件权限, 最高位的4表示文件类型为目
    录( 各种文件类型的编码详见stat(2)) , 低位的755表示权限
  • Size是1024, 说明根目录现在只有一个数据块。
  • Links为3表示根目录有三个硬链接, 分别是根目录下的 . 和 … , 以及 lost+found 子目录下的 … 。
  • 注意, 虽然我们通常用 / 表示根目录, 但是并没有名为 / 的硬链接, 事实上, / 是路径分隔符, 不能在文件名中出现
  • 这里的 Blockcount 是以512字节为一个块来数的, 并非格式化文件系统时所指定的块大小, 磁盘的最小读写单位称为扇区( Sector) , 通常是512字节, 所以 Blockcount 是磁盘的物理块数量, 而非分区的逻辑块数量。
  • 根目录数据块的位置由上图中的 Blocks[0] 指出, 也就是第24个块, 它在文件系统中的
    位置是24×0x400=0x6000, 从 od 命令的输出中找到006000地址, 它的格式是这样:
  • debugfs 也提供了 cd 、 ls 等命令, 不需要 mount 就可以查看这个文件系统中的目录, 例如用 ls 查看根目录:

3.数据块寻址