[关闭]
@harpsword 2015-11-26T13:38:44.000000Z 字数 8596 阅读 3136

linux0.11内核之文件系统

操作系统 文件系统


简述

linux0.11内核的文件系统主要参考了 Andrew S.Tanenbaum 所著的《操作系统:设计与实现》一书,使用了其中的MINIX1.0版。高速缓冲区的工作原理可以参考 M.J.Bach 的《UNIX操作系统设计》第三章内容。

一些细节

  1. 一个i节点结构一共32个字节,所以释放该i节点时采用的方法是 menset(inode,0,sizeof(*inode)),即置i节点结构所占内存区为0.
  2. i节点结构中的文件具体数据部分采用的是 unsigned short 类型,所以寻址能力是 216=65536bytes=64MB.而4G大小的内存应该使用232大小即4bytes来进行寻址。

总体功能描述

这个部分的代码可以从功能上分为四个部分:
1. 有关高速缓冲区的管理程序,主要实现了对硬盘等设备进行数据高速存取的函数。该部分内容集中在buffer.c程序中实现。
2. 文件系统的底层通用函数。说明了文件索引节点的管理、磁盘数据块的分配和释放以及文件名与i节点的转换算法
3. 对文件中数据进行读写操作的部分,包括对字符设备、管道、块读写文件中数据的访问
4. 与文件的系统调用接口的实现有关,主要涉及文件打开、关闭、创建、以及有关文件目录操作等的系统调用。

MINIX 文件系统(v1.0)

一个360KB软盘的结构图

MINIX文件系统和标准UNIX的文件系统基本相同,它由6个部分组成。对于一个360K的软盘,其各部分的分部如图所示。

MINIX1.png

图中,整个磁盘被划分为以1KB为单位的磁盘块,上图中每个方格代表一个磁盘块,在MINIX 1.0 文件系统中,其逻辑块大小和磁盘块大小正好都是 1 KB。

引导块

硬盘块设备

MINIX2.png

超级块

MINIX3.png

逻辑块位图

i节点位图

i节点结构图

i_mode 字段

i节点i_mode字段内容

文件的寻址
Created with Raphaël 2.1.2读取文件文件是否大于7KB使用 i_zone[7]找到一个盘块,这个盘块中存有512个盘块号,加上之前的i_zone[0]到i_zone[6]文件是否大于519KB使用i_zone[8]进行二次间接寻找,一共可以寻址512*512个盘块。读取数据over直接从 i_zone[0]到 i_zone[6]中得到盘块号yesnoyesno

关于逻辑块和磁盘块

文件系统结构

MINIX文件系统的目录项结构定义在 include/linux/fs.h 文件中. 在文件系统的一个目录中, 其中所有文件名信息对应的目录项都存储在该目录文件名文件(即目录文件)的数据块中。
文件名目录项结构如下所示:

  1. #define NAME_LEN 14 # 名字长度值
  2. #define ROOT_INO 1 # 根 i 节点
  3. # 大小 14 bytes
  4. struct dir_entry{
  5. unsigned short inode; # i 节点号 2 bytes
  6. char name[NAME_LEN]; # 文件名 14 bytes
  7. };

从中可知:

Created with Raphaël 2.1.2start从 inode 对应的磁盘块中,得到匹配的文件 i 节点 j,并更新 inode = j判断是否是要找的文件fileendnextfile = bin(举例)yesno

文件的链接

如下图,是从文件名获取数据块的图示:

从文件名获取数据块

从上图可以知道:
1. 在文件系统中,不同目录中的文件可以是同一个 i 节点,即存储时只存储一份,然后在对应的目录数据块中加入对应的目录项。
2. 每个i节点结构中都有一个链接计数字段 i_nlinks 记录着指向该i节点的目录项数,即文件的 硬链接数
3. 在执行删除文件的操作时, 只有当i节点链接计数值等于0时内核才会真正删除磁盘上该文件的数据。

硬链接

软链接(符号链接)

特殊的文件目录项

在每个目录中还包括两个特殊的文件目录项,分别是 '.' ,'..'。

重要

缓冲区

高速缓冲区
是文件系统访问块设备中数据的必经要道,是为了提高系统性能而设计的。

简述

缓冲区在内存中的位置

文件系统底层函数

文件系统的底层处理函数包括在以下5个文件中:

bitmap.c
包括对 i节点位图和逻辑块位图进行释放和占用处理函数。
truncate.c
包括对数据文件长度截断为0的函数 truncate().这个函数将i节点指定的设备上文件长度截为0,并释放文件数据占用的设备逻辑块。
inode.c
包括分配i节点函数 iget()和放回对内存i节点存取函数 iput() 以及根据i节点信息取文件数据块在设备上对应的逻辑块号函数 bmap()
namei.c
主要包括函数 namei().该函数使用 iget()、iput()、bmap()将给定的文件路径名映射到其 i节点。
super.c
专门用于处理文件系统超级块,包括 函数 get_super(),put_super(),free_super()等。还包括几个文件系统加载/卸载处理函数和系统调用,如sys_mount()等

这些文件中函数之间的层次关系如下图所示:
函数之间层次关系图

文件中数据的访问操作

关于文件中数据的访问操作,主要涉及5个文件:blk_dev.c,file_dev.c,char_dev.c,pipe.c和read_write.c。前四个可以认为是块设备、普通文件、字符设备、管道设备与文件读写系统调用的接口程序, 它们共同实现了read_write.c 中的read()和write()系统调用。 通过对被操作文件属性的判断,这两个系统调用会分别调用这些文件中的相关处理函数进行操作。这些函数之间的关系如下图:
关于文件中数据的访问操作函数之间的层次关系

block_dev.c

file_dev.c

pipe.c

    管道
管道主要用于在进程之间按照先进先出的方式传送数据,也可以用于使进程同步执行。

char_dev.c

实现机制

关系图

文件系统调用的上层实现

主要有五个文件,其层次结构如下图:

层次图

360KB软盘中文件系统实例分析

创建

利用linux0.11 系统在 360KB规格软盘映像中使用 mkfs 命令建立一个MINIXv1.0文件系统,其中只存放了一个名为hello.c的文件。

软盘数据

第一张
第二张

引导块部分

从之前的描述可以知道,MINIX 1.0 文件系统中 第1个盘块是 一个引导盘块。而且无论这个盘是否是引导盘,都会有引导盘块。对于这个例子,引导盘块应该全部为0,但是由于数据的遗留,所以没有全部为0.

超级块部分

超级块
是记录文件系统信息的。

盘块(0x0400-0x07ff,1KB)是超级块部分。我们已经知道超级块数据结构中共有18个字节中含有有效内容。由于每逻辑块对磁盘块的大小之比的对数值为 0, 所以 逻辑块大小等于 磁盘块大小。
具体数据如下

字段名称 超级块字段名称 内容
s_nindoes i节点数 0x0078 = 120 个
s_nzones 区块(逻辑块)数 0x0168 = 360 块
s_imap_blocks i节点位图所占块数 0x0001 = 1 块
s_zmap_blocks 区块位图所占块数 0x0001 = 1 块
s_firstdatazone 第一个数据块块号 0x0008
s_log_zone_size log2 (区块或逻辑块/盘块) 0x0000(表示逻辑块和盘块大小相同)
s_max_size 最大文件长度 0x10081c00 = 268966912字节
s_magic 文件系统魔数 0x137f

i节点位图

逻辑块位图

  1. block = nr + s_firstdatazone - 1
  2. nr = blcok - s_firstdatazone + 1

i节点结构信息

i节点结构数据

数据区

根目录文件内容

代码分析

问题

问题内容 解答
root目录的 '..' 目录项(root目录的父目录)
由于文件的链接数为0时才能真正删除文件,而文件的链接中必有'.', '..', 那如何删除'.','..'使得可以真正删除文件,或者文件无法真正删除
在例子中,有3个目录项,但是链接数为2 链接数是指指向该i节点的目录文件个数,在这个例子中只有两个指向该i节点,另外一个是文件
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注