Linux 文件系统之 MINIX 文件系统


MINIX 文件系统与标准 UNIX 的文件系统基本相同,它由 6 个部分组成:①引导块;②超级块;③ i 节点位图;④逻辑块位图;⑤i 节点;⑥数据块。对于一个普通的磁盘块设备来说,其各部分的分布见下图:


整个块设备被划分成以 1KB 为单位的磁盘块。


引导块是计算机加电启动时可由 ROM BIOS 自动读入的执行代码和数据盘块。但一个系统中并非所 有盘设备都用于作为引导设备,所以对于不用于引导的盘片,这一盘块中可以不含代码。但任何盘块设 备必须含有引导块空间,以保持 MINIX 文件系统格式的统一。即文件系统只是在块设备上空出一个存放 引导块的空间。如果你把内核映像文件放在文件系统中,那么你就可以在文件系统所在设备的第 1 个块 (即引导块空间)存放实际的引导程序,并由它来取得和加载文件系统中的内核映像文件。


对于容量巨大的硬盘块设备,通常会在其上会划分出几个分区,并且在每个分区中都可存放一个不 同的完整文件系统,见下图。



图中表示有 4 个分区,分别存放着 FAT32 文件系统、NTFS 文件系 统、MINIX 文件系统和 EXT2 文件系统。硬盘的第一个扇区是主引导扇区,其中存放着硬盘引导程序和 分区表信息。分区表中的信息指明了硬盘上每个分区的类型、在硬盘中起始位置参数和结束位置参数以 及占用的扇区总数,参见 kernel/blk_drv/hd.c 文件后的硬盘分区表结构


超级块用于存放盘设备上文件系统的结构信息,并说明各部分的大小。其结构见下图(MINIX 文件系统):



系统启动时会从磁盘的超级块中读取信息,初始化上图表中的数据结构。


其中, s_ninodes 表示设备上的 i 节点总数。s_nzones 表示设备上以逻辑块为单位的总逻辑块数。s_imap_blocks 和 s_zmap_blocks 分别表示 i 节点位图和逻辑块位图所占用的磁盘块数。s_firstdatazone 表示设备上数据 区开始处占用的第一个逻辑块块号。s_log_zone_size 是使用 2 为底的对数表示的每个逻辑块包含的磁盘 块数。对于 MINIX 1.0 文件系统该值为 0,因此其逻辑块的大小就等于磁盘块大小,都是 1KB。s_max_size 是以字节表示的最大文件长度,这里不超过 4GB。当然这个长度值将受到磁盘容量的限制。s_magic 是 文件系统魔幻数,用以指明文件系统的类型。


struct minix_sb_info {
unsigned long s_ninodes; //该成员用于描述 MINIX-FS 文件系统含有的 inode 数量。该值用于计算 Inode-Bitmap 和 Inode-Table 的大小
unsigned long s_nzones; //该成员用于描述 MINIX-FS 文件系统中含有的 Zone 的数量。该值用于计算 Zone-Bitmap。
unsigned long s_imap_blocks; //该成员用于描述 Inode-BitMap 占用 BLOCK_SIZE 的数量,Inode-BitMap 中的每个位表示一个 inode 的使用情况,如果某一个置位,那么对应的 minix_inode 就被使用,反之表示对应的 minix_inode 没有被使用。
unsigned long s_zmap_blocks; //该成员用于描述 Zone-BitMap 占用 BLOCK_SIZE 的数量。Zone-BitMap 中的 每个位表示一个 Zone 的使用情况,如果某一位置位,那么对应的 zone 就被 使用,反之表示对应的 zone 没有被使用。
//该成员用于描述第一个 data zone 所在的 block 号。Zone 分为两类,一类是 Reserved 的,用于存储 MINIX-FS 的系统信息,另外一类是 Data zone,用于 存储文件和目录的,而 s_firstdatazone 用于指向第一个 data zone 的 block 号
unsigned long s_firstdatazone;
//MINIX-FS 将文件系统分成 BLOCK_SIZE 大小的数据块,BLOCK_SIZE 的大小由 s_log_zone_size 决定,其计算方法如下:BLOCK_SIZE = 1024 << s_log_zone_size
unsigned long s_log_zone_size;
unsigned long s_max_size;
//s_imap[8] 是一个文件缓存数组。数组用于缓存 MINIX-FS 的所有 Inode-BitMap 内容。
struct buffer_head * s_imap[8];
//s_zmap[8] 是一个文件缓存数组,数组用于缓存 MINIX-FS 的所有 Zone-BitMap 内容
struct buffer_head * s_zmap[8];
//s_dirsize 用于描述 minix_dir_entry 结构的大小,minix_dir_entry 用于描述 一个 minix 目录。
unsigned long s_dirsize;
unsigned long s_namelen; //s_namelen 用于描述文件或目录名字的大小
struct buffer_head * s_sbh; //s_sbh 用于缓存磁盘中 MINIX-FS 的超级快信息
struct minix_super_block * s_ms; //s_ms 用于指向 minix_super_block 在内存中的位置。
unsigned short s_mount_state; //s_mount_state 用于描述 MINIX-FS 的 mount 状态。
};


较低版本系统中使用一个全局的super_blocks[]来保存超级块,该数据有多少元素也就支持多少个文件系统,高版本使用全局的super_blocks链表。


超级块表将在 super.c 程序的 mount_root()函 数中被初始化,在 read_super()函数中会为新加载的文件系统在表中设置一个超级块项,并在 put_super() 函数中释放超级块表中指定的超级块项。


逻辑块位图用于描述盘上每个数据盘块的使用情况。除第 1 个比特位(位 0)以外,逻辑块位图中 每个比特位依次代表盘上数据区中的一个逻辑块。因此逻辑块位图的比特位 1 代表盘上数据区中第一个 数据盘块,而非盘上的第一个磁盘块(引导块)。当一个数据盘块被占用时,则逻辑块位图中相应比特位 被置位。由于当所有磁盘数据盘块都被占用时查找空闲盘块的函数会返回 0 值,因此逻辑块位图最低比 特位(位 0)闲置不用,并且在创建文件系统时会预先将其设置为 1。


当向磁盘申请一个逻辑块时,对整个逻辑块位图进行搜索,寻找首个是 0

的比特位,该比特位所在的序号即为该数据库的逻辑块号,然后把逻辑块号保存到i_data[]中。


从超级块的结构中我们还可以看出,逻辑块位图最多使用 8 块缓冲块(s_zmap[8]),而每块缓冲块大小是 1024 字节,每比特表示一个盘块的占用状态,因此一个缓冲块可代表 8192 个盘块。8 个缓冲块 总共可表示 65536 个盘块,因此 MINIX 文件系统 1.0 所能支持的最大块设备容量(长度)是 64MB。


i 节点用于存放盘设备上每个文件和目录名的索引信息。i 节点位图用于说明 i 节点是否被使用,同 样是每个比特位代表一个 i 节点。对于 1K 大小的盘块来讲,一个盘块就可表示 8192 个 i 节点的使用状 况。与逻辑块位图的情况类似,由于当所有 i 节点都被使用时查找空闲 i 节点的函数会返回 0 值,因此 i 节点位图第 1 个字节的最低比特位(位 0)和对应的 i 节点 0 都闲置不用,并且在创建文件系统时会预 先将 i 节点 0 对应比特位图中的比特位置为 1。因此第一个 i 节点位图块中只能表示 8191 个 i 节点的状 况。


盘上的 i 节点部分存放着文件系统中文件或目录名的索引节点,每个文件或目录名都有一个 i 节点每个 i 节点结构中存放着对应文件或目录的相关信息。

所以图中


i_mode ... i_zone[] 这些一条条信息是保存到磁盘中的inode信息,当需要某个读取inode信息时,会从i节点中读取一条对应的inode信息保存到内存中,同时是使用 i_zone[]进行初始化 inode结构中的i_data[], 所以在内存中使用的是i_data[] 保存数据块地址,当同步inode节点时,把内存中的i_data[] 刷到磁盘i_zone[]中。


当创建一个inode节点时先从i节点位图中获取一个bit未使用的位,根据该bit位对应的位置下标(比如该bit位置为第1025的位置),根据下标从i节点中计算属于哪个数据块中,然后从对应的块中进行索引找到块中第n条i节点数据,

然后从该i节点数据中i_zone[]中即可获取或者存放数据。


如文件宿主的 id(uid)、文件所属组 id(gid)、文 件长度、访问修改时间以及文件数据块在盘上的位置等。整个 i 节点结构共使用 32 个字节,见下图所示:



i_mode 字段用来保存文件的类型和访问权限属性。其比特位 15-12 用于保存文件类型,位 11-9 保存 执行文件时设置的信息,位 8-0 表示文件的访问权限,见下图



文件中的数据存放在磁盘块的数据区中,而一个文件名则通过对应的 i 节点与这些数据磁盘块相联 系,这些盘块的号码就存放在 i 节点的逻辑块数组 i_zone[]中。其中,i_zone[]数组用于存放 i 节点对应文 件的盘块号。i_zone[0]到 i_zone[6]用于存放文件开始的 7 个磁盘块号,称为直接块。若文件长度小于等 于 7K 字节,则根据其 i 节点可以很快就找到它所使用的盘块。若文件大一些时,就需要用到一次间接块 了(i_zone[7]),这个盘块中存放着附加的盘块号。对于 MINIX 文件系统一个盘块中可以存放(1024 / 2) = 512 个盘块号,因此可以寻址 512 个盘块。若文件还要大,则需要使用二次间接盘块(i_zone[8])。二 次间接块的一级盘块的作用类似与一次间接盘块,因此使用二次间接盘块可以寻址 512*512 个盘块。参 见下图 所示:


所以对于 MINIX 文件系统 1.0 版来说,一个文件的最大长度为(7 + 512 + 512*512)= 262,663KB。


这些 i_zone[]信息是保存在磁盘中的,当读取inode时会把这些 i_zone[] 刷到inode 中的 i_data[] 中,也即是在内存中以 i_data[]方式存在。


另外,对于/dev/目录下的设备文件来说,它们并不占用磁盘数据区中的数据盘块,即它们文件的长 度是 0。设备文件名的 i 节点仅用于保存其所定义设备的属性和设备号。设备号被存放在设备文件 i 节点 的 zone[0]中。


当所有 i 节点都被使用时,查找空闲 i 节点的函数会返回值 0,因此,i 节点位图最低比特位和 i 节点 0 都闲置不用。i 节点 0 的结构被初始化成全零,并在创建文件系统时将 i 节点 0 的比特位置位。

参考文档

http://www.oldlinux.org/download/CLK-5.0-WithCover.pdf#page=648&zoom=100,72,450

展开阅读全文

页面更新:2024-05-24

标签:文件系统   位图   节点   磁盘   逻辑   大小   文件   数据   设备   信息

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top